Merge branch 'ventoy:master' into master

This commit is contained in:
gbrea 2024-10-15 08:48:17 +02:00 committed by GitHub
commit a5ae59c8c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
717 changed files with 33630 additions and 3701 deletions

4
.github/FUNDING.yml vendored
View File

@ -2,11 +2,11 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username liberapay: Ventoy
open_collective: ventoy
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
custom: ['https://www.paypal.me/ventoy', 'https://www.ventoy.net/en/donation.html'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] custom: ['https://www.paypal.me/ventoy', 'https://www.ventoy.net/en/donation.html'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -21,7 +21,7 @@ body:
attributes: attributes:
label: Ventoy Version label: Ventoy Version
description: What version of ventoy are you running? description: What version of ventoy are you running?
placeholder: 1.0.62 placeholder: 1.0.96
validations: validations:
required: true required: true
- type: dropdown - type: dropdown
@ -34,6 +34,16 @@ body:
- No. I didn't try the latest release. - No. I didn't try the latest release.
validations: validations:
required: true required: true
- type: dropdown
id: alternativemode
attributes:
label: Try alternative boot mode
description: Have you tried alternative boot mode? (wimboot mode for Windows/WinPE, grub2 mode for linux)
options:
- Yes. I have tried them, but the bug still exist.
- No. I didn't try these alternative boot modes.
validations:
required: true
- type: dropdown - type: dropdown
id: bios id: bios
attributes: attributes:

View File

@ -85,7 +85,7 @@ body:
- type: input - type: input
id: testenv id: testenv
attributes: attributes:
label: Test envrionment label: Test environment
description: The manufacturer/model and other details about your computer (or VM). description: The manufacturer/model and other details about your computer (or VM).
placeholder: Lenovo Thinkpad T420 laptop placeholder: Lenovo Thinkpad T420 laptop
validations: validations:

View File

@ -12,22 +12,26 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Run docker-compose up - name: Run docker-compose up
run: docker-compose up run: docker-compose up
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ventoy-windows name: ventoy-windows
path: INSTALL/ventoy-*windows* path: INSTALL/ventoy-*windows*
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ventoy-linux name: ventoy-linux
path: INSTALL/ventoy-*linux* path: INSTALL/ventoy-*linux*
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: ventoy-livecd name: ventoy-livecd
path: INSTALL/ventoy-*livecd* path: INSTALL/ventoy-*livecd*
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with:
name: SHA256SUM
path: INSTALL/sha256.txt
- uses: actions/upload-artifact@v3
with: with:
name: xxx-build-log name: xxx-build-log
path: DOC/build.log path: DOC/build.log

View File

@ -1,9 +1,11 @@
#!/bin/sh #!/bin/sh
DSTDIR=../../IMG/cpio/ventoy/busybox DSTDIR1=../../IMG/cpio_x86/ventoy/busybox
DSTDIR2=../../IMG/cpio_arm64/ventoy/busybox
DSTDIR3=../../IMG/cpio_mips64/ventoy/busybox
rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64 rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64
rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64 $DSTDIR/vtchmodm64e rm -f $DSTDIR1/vtchmod32 $DSTDIR1/vtchmod64 $DSTDIR2/vtchmodaa64 $DSTDIR3/vtchmodm64e
/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32 /opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32
/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64 /opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64
@ -23,9 +25,9 @@ chmod 777 vtchmodaa64
chmod 777 vtchmod64_musl chmod 777 vtchmod64_musl
chmod 777 vtchmodm64e chmod 777 vtchmodm64e
cp -a vtchmod32 $DSTDIR/ cp -a vtchmod32 $DSTDIR1/
cp -a vtchmod64 $DSTDIR/ cp -a vtchmod64 $DSTDIR1/
cp -a vtchmodaa64 $DSTDIR/ cp -a vtchmod64_musl $DSTDIR1/
cp -a vtchmod64_musl $DSTDIR/ cp -a vtchmodaa64 $DSTDIR2/
cp -a vtchmodm64e $DSTDIR/ cp -a vtchmodm64e $DSTDIR3/

View File

@ -1,5 +1,8 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/utsname.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@ -8,6 +11,24 @@ int main(int argc, char **argv)
return 1; return 1;
} }
if (argv[1][0] == '-' && argv[1][1] == '6')
{
struct utsname buf;
if (0 == uname(&buf))
{
if (strstr(buf.machine, "amd64"))
{
return 0;
}
if (strstr(buf.machine, "x86_64"))
{
return 0;
}
}
return 1;
}
return chmod(argv[1], 0777); return chmod(argv[1], 0777);
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

7
DMPATCH/Makefile Normal file
View File

@ -0,0 +1,7 @@
obj-m += dm_patch.o
EXTRA_CFLAGS := -Wall
dm_patch-objs := dmpatch.o

7
DMPATCH/Makefile_IBT Normal file
View File

@ -0,0 +1,7 @@
obj-m += dm_patch_ibt.o
EXTRA_CFLAGS := -Wall -DVTOY_IBT -fcf-protection=branch -mindirect-branch-register
dm_patch_ibt-objs := dmpatch.o

632
DMPATCH/dmpatch.c Normal file
View File

@ -0,0 +1,632 @@
/******************************************************************************
* dmpatch.c ---- patch for device-mapper
*
* Copyright (c) 2021, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/mempool.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/slab.h>
#define MAX_PATCH 4
#define magic_sig 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
typedef int (*kprobe_reg_pf)(void *);
typedef void (*kprobe_unreg_pf)(void *);
typedef int (*printk_pf)(const char *fmt, ...);
typedef int (*set_memory_attr_pf)(unsigned long addr, int numpages);
#pragma pack(1)
typedef struct ko_param
{
unsigned char magic[16];
unsigned long struct_size;
unsigned long pgsize;
unsigned long printk_addr;
unsigned long ro_addr;
unsigned long rw_addr;
unsigned long reg_kprobe_addr;
unsigned long unreg_kprobe_addr;
unsigned long sym_get_addr;
unsigned long sym_get_size;
unsigned long sym_put_addr;
unsigned long sym_put_size;
unsigned long kv_major;
unsigned long ibt;
unsigned long kv_minor;
unsigned long blkdev_get_addr;
unsigned long blkdev_put_addr;
unsigned long bdev_open_addr;
unsigned long kv_subminor;
unsigned long bdev_file_open_addr;
unsigned long padding[1];
}ko_param;
#pragma pack()
static printk_pf kprintf = NULL;
static set_memory_attr_pf set_mem_ro = NULL;
static set_memory_attr_pf set_mem_rw = NULL;
static kprobe_reg_pf reg_kprobe = NULL;
static kprobe_unreg_pf unreg_kprobe = NULL;
static volatile ko_param g_ko_param =
{
{ magic_sig },
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#if defined(CONFIG_X86_64)
#define PATCH_OP_POS1 3
#define CODE_MATCH1(code, i) \
(code[i] == 0x40 && code[i + 1] == 0x80 && code[i + 2] == 0xce && code[i + 3] == 0x80)
#define PATCH_OP_POS2 1
#define CODE_MATCH2(code, i) \
(code[i] == 0x0C && code[i + 1] == 0x80 && code[i + 2] == 0x89 && code[i + 3] == 0xC6)
#define PATCH_OP_POS3 4
#define CODE_MATCH3(code, i) \
(code[i] == 0x44 && code[i + 1] == 0x89 && code[i + 2] == 0xe8 && code[i + 3] == 0x0c && code[i + 4] == 0x80)
#elif defined(CONFIG_X86_32)
#define PATCH_OP_POS1 2
#define CODE_MATCH1(code, i) \
(code[i] == 0x80 && code[i + 1] == 0xca && code[i + 2] == 0x80 && code[i + 3] == 0xe8)
#define PATCH_OP_POS2 PATCH_OP_POS1
#define CODE_MATCH2 CODE_MATCH1
#define PATCH_OP_POS3 PATCH_OP_POS1
#define CODE_MATCH3 CODE_MATCH1
#else
#error "unsupported arch"
#endif
#ifdef VTOY_IBT
#ifdef CONFIG_X86_64
/* Using 64-bit values saves one instruction clearing the high half of low */
#define DECLARE_ARGS(val, low, high) unsigned long low, high
#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32)
#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
#else
#define DECLARE_ARGS(val, low, high) unsigned long long val
#define EAX_EDX_VAL(val, low, high) (val)
#define EAX_EDX_RET(val, low, high) "=A" (val)
#endif
#define EX_TYPE_WRMSR 8
#define EX_TYPE_RDMSR 9
#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */
#define CET_ENDBR_EN (1ULL << 2)
/* Exception table entry */
#ifdef __ASSEMBLY__
#define _ASM_EXTABLE_TYPE(from, to, type) \
.pushsection "__ex_table","a" ; \
.balign 4 ; \
.long (from) - . ; \
.long (to) - . ; \
.long type ; \
.popsection
#else /* ! __ASSEMBLY__ */
#define _ASM_EXTABLE_TYPE(from, to, type) \
" .pushsection \"__ex_table\",\"a\"\n" \
" .balign 4\n" \
" .long (" #from ") - .\n" \
" .long (" #to ") - .\n" \
" .long " __stringify(type) " \n" \
" .popsection\n"
#endif /* __ASSEMBLY__ */
#endif /* VTOY_IBT */
#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
static unsigned int g_claim_ptr = 0;
static unsigned char *g_get_patch[MAX_PATCH] = { NULL };
static unsigned char *g_put_patch[MAX_PATCH] = { NULL };
static int notrace dmpatch_kv_above(unsigned long Major, unsigned long Minor, unsigned long SubMinor)
{
if (g_ko_param.kv_major != Major)
{
return (g_ko_param.kv_major > Major) ? 1 : 0;
}
if (g_ko_param.kv_minor != Minor)
{
return (g_ko_param.kv_minor > Minor) ? 1 : 0;
}
if (g_ko_param.kv_subminor != SubMinor)
{
return (g_ko_param.kv_subminor > SubMinor) ? 1 : 0;
}
return 1;
}
static void notrace dmpatch_restore_code(int bytes, unsigned char *opCode, unsigned int code)
{
unsigned long align;
if (opCode)
{
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
if (bytes == 1)
{
*opCode = (unsigned char)code;
}
else
{
*(unsigned int *)opCode = code;
}
set_mem_ro(align, 1);
}
}
static int notrace dmpatch_replace_code
(
int style,
unsigned long addr,
unsigned long size,
int expect,
const char *desc,
unsigned char **patch
)
{
int i = 0;
int cnt = 0;
unsigned long align;
unsigned char *opCode = (unsigned char *)addr;
vdebug("patch for %s style[%d] 0x%lx %d\n", desc, style, addr, (int)size);
for (i = 0; i < (int)size - 8; i++)
{
if (style == 1)
{
if (CODE_MATCH1(opCode, i) && cnt < MAX_PATCH)
{
patch[cnt] = opCode + i + PATCH_OP_POS1;
cnt++;
}
}
else if (style == 2)
{
if (CODE_MATCH2(opCode, i) && cnt < MAX_PATCH)
{
patch[cnt] = opCode + i + PATCH_OP_POS2;
cnt++;
}
}
else if (style == 3)
{
if (CODE_MATCH3(opCode, i) && cnt < MAX_PATCH)
{
patch[cnt] = opCode + i + PATCH_OP_POS3;
cnt++;
}
}
}
if (cnt != expect || cnt >= MAX_PATCH)
{
vdebug("patch error: cnt=%d expect=%d\n", cnt, expect);
return 1;
}
for (i = 0; i < cnt; i++)
{
opCode = patch[i];
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
*opCode = 0;
set_mem_ro(align, 1);
}
return 0;
}
static unsigned long notrace dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func)
{
unsigned long i = 0;
unsigned long dest;
unsigned char *opCode = NULL;
unsigned char aucOffset[8] = { 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
opCode = (unsigned char *)addr;
for (i = 0; i + 4 < size; i++)
{
if (opCode[i] == 0xE8)
{
aucOffset[0] = opCode[i + 1];
aucOffset[1] = opCode[i + 2];
aucOffset[2] = opCode[i + 3];
aucOffset[3] = opCode[i + 4];
dest = addr + i + 5 + *(unsigned long *)aucOffset;
if (dest == func)
{
return i;
}
}
}
return 0;
}
static unsigned int notrace dmpatch_patch_claim_ptr(void)
{
unsigned long i = 0;
unsigned long t = 0;
unsigned long offset1 = 0;
unsigned long offset2 = 0;
unsigned long align = 0;
unsigned char *opCode = NULL;
opCode = (unsigned char *)g_ko_param.sym_get_addr;
for (i = 0; i < 4; i++)
{
vdebug("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
opCode[i + 0], opCode[i + 1], opCode[i + 2], opCode[i + 3],
opCode[i + 4], opCode[i + 5], opCode[i + 6], opCode[i + 7],
opCode[i + 8], opCode[i + 9], opCode[i + 10], opCode[i + 11],
opCode[i + 12], opCode[i + 13], opCode[i + 14], opCode[i + 15]);
}
if (dmpatch_kv_above(6, 7, 0)) /* >= 6.7 kernel */
{
vdebug("Get addr: 0x%lx %lu open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_open_addr);
if (offset1 == 0)
{
vdebug("call bdev_open_addr Not found\n");
vdebug("Get addr: 0x%lx %lu file_open 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.bdev_file_open_addr);
if (offset1 == 0)
{
vdebug("call bdev_file_open_addr Not found\n");
return 1;
}
}
}
else
{
vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
if (offset1 == 0 || offset2 == 0)
{
vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2);
return 1;
}
}
vdebug("call addr1:0x%lx call addr2:0x%lx\n",
g_ko_param.sym_get_addr + offset1,
g_ko_param.sym_put_addr + offset2);
opCode = (unsigned char *)g_ko_param.sym_get_addr;
for (i = offset1 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
{
/* rdx */
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc2)
{
g_claim_ptr = *(unsigned int *)(opCode + i + 3);
g_get_patch[0] = opCode + i + 3;
vdebug("claim_ptr(%08X) found at get addr 0x%lx\n", g_claim_ptr, g_ko_param.sym_get_addr + i + 3);
break;
}
}
if (g_claim_ptr == 0)
{
vdebug("Claim_ptr not found in get\n");
return 1;
}
align = (unsigned long)g_get_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
*(unsigned int *)(g_get_patch[0]) = 0;
set_mem_ro(align, 1);
if (offset2 > 0)
{
opCode = (unsigned char *)g_ko_param.sym_put_addr;
for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
{
/* rsi */
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6)
{
if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr)
{
vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3);
g_put_patch[0] = opCode + i + 3;
break;
}
}
}
if (g_put_patch[0] == 0)
{
vdebug("Claim_ptr not found in put\n");
return 1;
}
align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
*(unsigned int *)(g_put_patch[0]) = 0;
set_mem_ro(align, 1);
}
return 0;
}
#ifdef VTOY_IBT
static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr)
{
DECLARE_ARGS(val, low, high);
asm volatile("1: rdmsr\n"
"2:\n"
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR)
: EAX_EDX_RET(val, low, high) : "c" (msr));
return EAX_EDX_VAL(val, low, high);
}
static __always_inline void dmpatch_wrmsr(unsigned int msr, u32 low, u32 high)
{
asm volatile("1: wrmsr\n"
"2:\n"
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
: : "c" (msr), "a"(low), "d" (high) : "memory");
}
static u64 notrace dmpatch_ibt_save(void)
{
u64 msr = 0;
u64 val = 0;
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
val = msr & ~CET_ENDBR_EN;
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(val & 0xffffffffULL), (u32)(val >> 32));
return msr;
}
static void notrace dmpatch_ibt_restore(u64 save)
{
u64 msr;
msr = dmpatch_rdmsr(MSR_IA32_S_CET);
msr &= ~CET_ENDBR_EN;
msr |= (save & CET_ENDBR_EN);
dmpatch_wrmsr(MSR_IA32_S_CET, (u32)(msr & 0xffffffffULL), (u32)(msr >> 32));
}
#else
static u64 notrace dmpatch_ibt_save(void) { return 0; }
static void notrace dmpatch_ibt_restore(u64 save) { (void)save; }
#endif
static int notrace dmpatch_process(unsigned long a, unsigned long b, unsigned long c)
{
int r = 0;
int rc = 0;
unsigned long kv_major = 0;
unsigned long kv_minor = 0;
unsigned long kv_subminor = 0;
vdebug("dmpatch_process as KV %d.%d.%d ...\n", (int)a, (int)b, (int)c);
kv_major = g_ko_param.kv_major;
kv_minor = g_ko_param.kv_minor;
kv_subminor = g_ko_param.kv_subminor;
g_ko_param.kv_major = a;
g_ko_param.kv_minor = b;
g_ko_param.kv_subminor = c;
if (dmpatch_kv_above(6, 5, 0)) /* >= kernel 6.5 */
{
vdebug("new interface patch dm_get_table_device...\n");
r = dmpatch_patch_claim_ptr();
}
else
{
r = dmpatch_replace_code(1, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device", g_get_patch);
if (r && g_ko_param.kv_major >= 5)
{
vdebug("new2 patch dm_get_table_device...\n");
r = dmpatch_replace_code(2, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
}
if (r && g_ko_param.kv_major >= 5)
{
vdebug("new3 patch dm_get_table_device...\n");
r = dmpatch_replace_code(3, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
}
}
if (r)
{
rc = -EFAULT;
goto out;
}
vdebug("patch dm_get_table_device success\n");
if (dmpatch_kv_above(6, 5, 0))
{
r = 0;
}
else
{
r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch);
if (r)
{
rc = -EFAULT;
goto out;
}
vdebug("patch dm_put_table_device success\n");
}
vdebug("#####################################\n");
vdebug("######## dm patch success ###########\n");
vdebug("#####################################\n");
out:
g_ko_param.kv_major = kv_major;
g_ko_param.kv_minor = kv_minor;
g_ko_param.kv_subminor = kv_subminor;
return rc;
}
static int notrace dmpatch_init(void)
{
int rc = 0;
u64 msr = 0;
if (g_ko_param.ibt == 0x8888)
{
msr = dmpatch_ibt_save();
}
kprintf = (printk_pf)(g_ko_param.printk_addr);
vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu.%lu ...\n",
g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
if (g_ko_param.struct_size != sizeof(ko_param))
{
vdebug("Invalid struct size %d %d\n", (int)g_ko_param.struct_size, (int)sizeof(ko_param));
return -EINVAL;
}
if (g_ko_param.sym_get_addr == 0 || g_ko_param.sym_put_addr == 0 ||
g_ko_param.ro_addr == 0 || g_ko_param.rw_addr == 0)
{
return -EINVAL;
}
set_mem_ro = (set_memory_attr_pf)(g_ko_param.ro_addr);
set_mem_rw = (set_memory_attr_pf)(g_ko_param.rw_addr);
reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr;
unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr;
rc = dmpatch_process(g_ko_param.kv_major, g_ko_param.kv_minor, g_ko_param.kv_subminor);
if (rc)
{
if (g_ko_param.kv_major >= 5)
{
rc = dmpatch_process(6, 5, 0);
if (rc)
{
rc = dmpatch_process(6, 7, 0);
}
}
}
if (g_ko_param.ibt == 0x8888)
{
dmpatch_ibt_restore(msr);
}
return rc;
}
static void notrace dmpatch_exit(void)
{
int i = 0;
u64 msr;
if (g_ko_param.ibt == 0x8888)
{
msr = dmpatch_ibt_save();
}
if (g_claim_ptr)
{
dmpatch_restore_code(4, g_get_patch[0], g_claim_ptr);
if (g_put_patch[0])
{
dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr);
}
}
else
{
for (i = 0; i < MAX_PATCH; i++)
{
dmpatch_restore_code(1, g_get_patch[i], 0x80);
dmpatch_restore_code(1, g_put_patch[i], 0x80);
}
}
vdebug("dmpatch_exit success\n");
if (g_ko_param.ibt == 0x8888)
{
dmpatch_ibt_restore(msr);
}
}
module_init(dmpatch_init);
module_exit(dmpatch_exit);
MODULE_DESCRIPTION("dmpatch driver");
MODULE_AUTHOR("longpanda <admin@ventoy.net>");
MODULE_LICENSE("GPL");

38
DMPATCH/readme.txt Normal file
View File

@ -0,0 +1,38 @@
1. install ubuntu 22.04 5.15.0-25
2. apt-get install build-essential flex libncurses-dev linux-headers-generic linux-source libssl-dev bison yacc vim libelf-dev ...... and so on
3. cp /lib/modules/5.15.0-25-generic/build/Module.symvers ./
4. /boot/config-5.15.0-25-generic as .config make oldconfig
5. make menuconfig
1. close CONFIG_STACKPROTECTOR
2. close CONFIG_RETPOLINE
3. close CONFIG_UBSAN_BOUNDS
4. close CONFIG_UBSAN_ENUM
6. modify ./scripts/mod/modpost.c
1. skip add_srcversion (just return)
2. force add_retpoline (#ifdef --> #ifndef)
3. force add_intree_flag
7. make modules_prepare LOCALVERSION=-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
8. Append padding at the end of struct module <include/linux/module.h>
struct module {
enum module_state state;
/* Member of list of modules */
struct list_head list;
/* Unique handle for this module */
char name[MODULE_NAME_LEN];
....
char padding[1024];
};
This is because struct module size is different in different kernel versions or with different CONFIG item.
9. make modules M=/home/dmpatch
10. strip --strip-debug /home/dmpatch/dm_patch.ko

65
DMPATCH/ubuntu_build.sh Normal file
View File

@ -0,0 +1,65 @@
#!/bin/bash
FTPIP=192.168.44.1
FTPUSR='a:a'
rm -f dmpatch.c Makefile Makefile_IBT
for f in dmpatch.c Makefile Makefile_IBT; do
curl -s -u $FTPUSR ftp://$FTPIP/$f -o $f
if [ -f $f ]; then
echo "download $f OK ..."
else
echo "download $f FAILED ..."
exit 1
fi
done
rm -f *.ko
echo "build dm_patch.ko ..."
rm -rf ./aa
mkdir ./aa
cp -a *.c aa/
cp -a Makefile aa/
cd /home/panda/linux-source-5.15.0
make modules M=/home/panda/build/aa/
strip --strip-debug /home/panda/build/aa/dm_patch.ko
cd -
cp -a aa/dm_patch.ko ./
echo "build dm_patch_ibt.ko ..."
rm -rf ./aa
mkdir ./aa
cp -a *.c aa/
cp -a Makefile_IBT aa/Makefile
cd /home/panda/linux-source-5.15.0
make modules M=/home/panda/build/aa/
strip --strip-debug /home/panda/build/aa/dm_patch_ibt.ko
cd -
cp -a aa/dm_patch_ibt.ko ./
rm -rf ./aa
curl -s -T dm_patch.ko -u $FTPUSR ftp://$FTPIP/dm_patch_64.ko || exit 1
curl -s -T dm_patch_ibt.ko -u $FTPUSR ftp://$FTPIP/dm_patch_ibt_64.ko || exit 1
if [ -f ./dm_patch.ko -a -f ./dm_patch_ibt.ko ]; then
echo -e "\n\n=============== SUCCESS =============\n\n"
else
echo -e "\n\n=============== FAILED ==============\n\n"
fi

View File

@ -5,7 +5,7 @@ use an old version of dmsetup
http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz
======== Build Envrioment ======== ======== Build Environment ========
build for 32bit, static linked with dietlibc build for 32bit, static linked with dietlibc
1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso 1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso
2. yum install gcc kernel-devel package 2. yum install gcc kernel-devel package

View File

@ -1,9 +1,9 @@
========================================== ==========================================
1. Compile Enviroment 1. Compile Environment
========================================== ==========================================
My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch. My build environment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch.
Because Ventoy is based on many open source projects, so the environment is important. I suggest you test it on a virtual machine firstly. Ventoy is based on many open source projects, so the build environment is important. I suggest you first test it on a virtual machine.
1.1 Install CentOS 7.8 1.1 Install CentOS 7.8
I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install
@ -21,10 +21,10 @@
========================================== ==========================================
2. Download Source Code 2. Download Source Code
========================================== ==========================================
2.1 Download Ventoy source code from github and decompress it. 2.1 Download Ventoy source code from GitHub and decompress it.
Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory layout). Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory layout).
2.2 Download third-part source code and tool 2.2 Download third-party source code and tool
https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz
https://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz https://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz
@ -34,7 +34,7 @@
https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip
https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2
http://ftp.loongnix.org/toolchain/gcc/release/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz
https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2 https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2
@ -42,7 +42,7 @@
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz
http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz
2.3 Prepare third-part tools 2.3 Prepare third-party tools
cd /home/Ventoy-master/DOC/ cd /home/Ventoy-master/DOC/
tar xf musl-1.2.1.tar.gz tar xf musl-1.2.1.tar.gz
cd musl-1.2.1 cd musl-1.2.1
@ -54,7 +54,7 @@
mv /opt/output /opt/mips64el-linux-musl-gcc730 mv /opt/output /opt/mips64el-linux-musl-gcc730
2.4 Set PATH envrioment 2.4 Set PATH environment
export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin
better to add this line to /root/.bashrc and relogin as root better to add this line to /root/.bashrc and relogin as root
@ -62,21 +62,21 @@
========================================== ==========================================
3. All in one script 3. All in one script
========================================== ==========================================
I have made a all_in_one.sh, you can run this script to build and pack ventoy. I have made an all-in-one script `all_in_one.sh`. You can run this script to build and pack ventoy.
If you want to compile a certain part separately, you can continue to refer to the later chapters of this text. If you want to compile a certain part separately, you can continue to refer to the later chapters of this text.
cd /home/Ventoy-master/INSTALL cd /home/Ventoy-master/INSTALL
sh all_in_one.sh sh all_in_one.sh
It should be noted that: It should be noted that:
1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other part contains the binaries and are few modified, so will no be recompiled everytime. 1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other parts contain binaries and are rarely modified, so will not be recompiled everytime.
You can rebuild these parts separately if you want. You can rebuild these parts separately if you want.
2. some part of Ventoy has 32bit&64bit version (like 4.9 4.10 4.11 follows) 2. Some parts of Ventoy have a 32-bit and 64-bit version (like 4.9, 4.10, 4.11 follows)
all_in_one.sh only build 64bit version of them, if you want to rebuild the 32bit verison. You should create a 32bit CentOS environment and build them. all_in_one.sh only builds the 64bit version of them. If you want to rebuild the 32bit verison, you should create a 32-bit CentOS environment and build them.
Fortunately these parts are few modified, you only need to build once or you can directly use the binary I have built. Fortunately these parts are rarely modified, so you only need to build once or you can directly use the binaries I have built.
Besides, after a fully compile and pack, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package. Besides, after a full compile and packaging, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package.
========================================== ==========================================
4. Build every part of Ventoy 4. Build every part of Ventoy
@ -108,10 +108,10 @@
cd /home/Ventoy-master/VtoyTool cd /home/Ventoy-master/VtoyTool
sh build.sh sh build.sh
4.8 == Build vtoyfat == 4.8 == Build vtoycli ==
cd /home/Ventoy-master/vtoyfat/fat_io_lib cd /home/Ventoy-master/vtoycli/fat_io_lib
sh buildlib.sh sh buildlib.sh
cd /home/Ventoy-master/vtoyfat cd /home/Ventoy-master/vtoycli
sh build.sh sh build.sh
4.9 == Build exfat-util == 4.9 == Build exfat-util ==
@ -122,14 +122,14 @@
After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64 After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64
After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64 After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64
Use the same build step to build exfat-util 32bit in a 32bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32 Use the same build step to build exfat-util 32-bit in a 32-bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32
4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 == 4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 ==
cd /home/Ventoy-master/FUSEISO cd /home/Ventoy-master/FUSEISO
sh build_libfuse.sh sh build_libfuse.sh
sh build.sh sh build.sh
Use the same build step to build in a 32bit CentOS system and get vtoy_fuse_iso_32 Use the same build step to build in a 32-bit CentOS system and get vtoy_fuse_iso_32
4.11 == Build unsquashfs_64/unsquashfs_32 == 4.11 == Build unsquashfs_64/unsquashfs_32 ==
cd /home/Ventoy-master/SQUASHFS/SRC cd /home/Ventoy-master/SQUASHFS/SRC
@ -141,7 +141,7 @@
cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools
sh build.sh sh build.sh
Use the same build step to build in a 32bit CentOS system and get unsquashfs_32 Use the same build step to build in a 32-bit CentOS system and get unsquashfs_32
4.12 == Build vblade_64/vblade_32 == 4.12 == Build vblade_64/vblade_32 ==
cd /home/Ventoy-master/VBLADE/vblade-master cd /home/Ventoy-master/VBLADE/vblade-master

View File

@ -249,6 +249,12 @@ EFI_STATUS EFIAPI vdisk_exit_boot_service_wrapper
IN UINTN MapKey IN UINTN MapKey
) )
{ {
if (g_org_get_variable)
{
gRT->GetVariable = g_org_get_variable;
g_org_get_variable = NULL;
}
return g_org_exit_boot_service(ImageHandle, MapKey); return g_org_exit_boot_service(ImageHandle, MapKey);
} }

View File

@ -60,7 +60,7 @@ ventoy_grub_param_file_replace *g_file_replace_list = NULL;
ventoy_efi_file_replace g_efi_file_replace; ventoy_efi_file_replace g_efi_file_replace;
ventoy_grub_param_file_replace *g_img_replace_list = NULL; ventoy_grub_param_file_replace *g_img_replace_list = NULL;
ventoy_efi_file_replace g_img_file_replace; ventoy_efi_file_replace g_img_file_replace[VTOY_MAX_CONF_REPLACE];
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH; CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH; CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH;
@ -71,6 +71,9 @@ STATIC BOOLEAN g_hook_keyboard = FALSE;
CHAR16 gFirstTryBootFile[256] = {0}; CHAR16 gFirstTryBootFile[256] = {0};
STATIC EFI_GET_VARIABLE g_org_get_variable = NULL;
STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL;
/* Boot filename */ /* Boot filename */
UINTN gBootFileStartIndex = 1; UINTN gBootFileStartIndex = 1;
CONST CHAR16 *gEfiBootFileName[] = CONST CHAR16 *gEfiBootFileName[] =
@ -226,12 +229,14 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain)
debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size); debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size);
debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr); debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr);
debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len); debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len);
debug("os_param->vtoy_reserved=<%u %u %u %u %u>", debug("os_param->vtoy_reserved=<%u %u %u %u %u %u %u>",
g_os_param_reserved[0], g_os_param_reserved[0],
g_os_param_reserved[1], g_os_param_reserved[1],
g_os_param_reserved[2], g_os_param_reserved[2],
g_os_param_reserved[3], g_os_param_reserved[3],
g_os_param_reserved[4] g_os_param_reserved[4],
g_os_param_reserved[5],
g_os_param_reserved[6]
); );
ventoy_debug_pause(); ventoy_debug_pause();
@ -572,10 +577,11 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
continue; continue;
} }
if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0) if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0 &&
CompareMem(g_chain->os_param.vtoy_disk_signature, pBuffer + 0x1b8, 4) == 0)
{ {
pMBR = (MBR_HEAD *)pBuffer; pMBR = (MBR_HEAD *)pBuffer;
if (pMBR->PartTbl[0].FsFlag != 0xEE) if (g_os_param_reserved[6] == 0 && pMBR->PartTbl[0].FsFlag != 0xEE)
{ {
if (pMBR->PartTbl[0].StartSectorId != 2048 || if (pMBR->PartTbl[0].StartSectorId != 2048 ||
pMBR->PartTbl[1].SectorCount != 65536 || pMBR->PartTbl[1].SectorCount != 65536 ||
@ -594,7 +600,7 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
Handles[i], Handles[i],
EFI_OPEN_PROTOCOL_GET_PROTOCOL); EFI_OPEN_PROTOCOL_GET_PROTOCOL);
debug("Find Ventoy Disk Handle:%p DP:%s", Handles[i], debug("Find Ventoy Disk Sig Handle:%p DP:%s", Handles[i],
ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE)); ConvertDevicePathToText(gBlockData.pDiskDevPath, FALSE, FALSE));
break; break;
} }
@ -739,6 +745,77 @@ STATIC EFI_STATUS ventoy_proc_img_replace_name(ventoy_grub_param_file_replace *r
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS EFIAPI ventoy_get_variable_wrapper
(
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes, OPTIONAL
IN OUT UINTN *DataSize,
OUT VOID *Data OPTIONAL
)
{
EFI_STATUS Status = EFI_SUCCESS;
Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data);
if (StrCmp(VariableName, L"SecureBoot") == 0)
{
if ((*DataSize == 1) && Data)
{
*(UINT8 *)Data = 0;
}
}
return Status;
}
EFI_STATUS EFIAPI ventoy_exit_boot_service_wrapper
(
IN EFI_HANDLE ImageHandle,
IN UINTN MapKey
)
{
if (g_org_get_variable)
{
gRT->GetVariable = g_org_get_variable;
g_org_get_variable = NULL;
}
return g_org_exit_boot_service(ImageHandle, MapKey);
}
STATIC EFI_STATUS EFIAPI ventoy_disable_secure_boot(IN EFI_HANDLE ImageHandle)
{
UINT8 Value = 0;
UINTN DataSize = 1;
EFI_STATUS Status = EFI_SUCCESS;
Status = gRT->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &DataSize, &Value);
if (!EFI_ERROR(Status))
{
if (DataSize == 1 && Value == 0)
{
debug("Current secure boot is off, no need to disable");
return EFI_SUCCESS;
}
}
debug("ventoy_disable_secure_boot");
/* step1: wrapper security protocol. */
/* Do we still need it since we have been loaded ? */
/* step2: fake SecureBoot variable */
g_org_exit_boot_service = gBS->ExitBootServices;
gBS->ExitBootServices = ventoy_exit_boot_service_wrapper;
g_org_get_variable = gRT->GetVariable;
gRT->GetVariable = ventoy_get_variable_wrapper;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
{ {
UINT32 i = 0; UINT32 i = 0;
@ -752,6 +829,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
ventoy_grub_param *pGrubParam = NULL; ventoy_grub_param *pGrubParam = NULL;
EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL;
ventoy_chain_head *chain = NULL; ventoy_chain_head *chain = NULL;
ventoy_grub_param_file_replace *replace = NULL;
Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo);
if (EFI_ERROR(Status)) if (EFI_ERROR(Status))
@ -849,18 +927,27 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
old_cnt > 3 ? g_file_replace_list->old_file_name[3] : "" old_cnt > 3 ? g_file_replace_list->old_file_name[3] : ""
); );
g_img_replace_list = &pGrubParam->img_replace;
ventoy_proc_img_replace_name(g_img_replace_list); for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++)
old_cnt = g_img_replace_list->old_file_cnt; {
debug("img replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>", replace = pGrubParam->img_replace + i;
g_img_replace_list->magic, if (replace->magic == GRUB_IMG_REPLACE_MAGIC)
g_img_replace_list->new_file_virtual_id, {
ventoy_proc_img_replace_name(replace);
old_cnt = replace->old_file_cnt;
debug("img replace[%d]: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
i, replace->magic,
replace->new_file_virtual_id,
old_cnt, old_cnt,
old_cnt > 0 ? g_img_replace_list->old_file_name[0] : "", old_cnt > 0 ? replace->old_file_name[0] : "",
old_cnt > 1 ? g_img_replace_list->old_file_name[1] : "", old_cnt > 1 ? replace->old_file_name[1] : "",
old_cnt > 2 ? g_img_replace_list->old_file_name[2] : "", old_cnt > 2 ? replace->old_file_name[2] : "",
old_cnt > 3 ? g_img_replace_list->old_file_name[3] : "" old_cnt > 3 ? replace->old_file_name[3] : ""
); );
g_img_replace_list = pGrubParam->img_replace;
}
}
pPos = StrStr(pCmdLine, L"mem:"); pPos = StrStr(pCmdLine, L"mem:");
chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
@ -882,6 +969,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
debug("memdisk mode iso_buf_size:%u", g_iso_buf_size); debug("memdisk mode iso_buf_size:%u", g_iso_buf_size);
g_chain = chain; g_chain = chain;
g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved);
gMemdiskMode = TRUE; gMemdiskMode = TRUE;
} }
else else
@ -910,6 +998,11 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
g_hook_keyboard = TRUE; g_hook_keyboard = TRUE;
} }
if (g_os_param_reserved[5] == 1 && g_os_param_reserved[2] == ventoy_chain_linux)
{
ventoy_disable_secure_boot(ImageHandle);
}
debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard); debug("internal param: secover:%u keyboard:%u", g_fixup_iso9660_secover_enable, g_hook_keyboard);
for (i = 0; i < sizeof(ventoy_os_param); i++) for (i = 0; i < sizeof(ventoy_os_param); i++)
@ -1095,8 +1188,7 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
gST->ConIn->Reset(gST->ConIn, FALSE); gST->ConIn->Reset(gST->ConIn, FALSE);
} }
if ((g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) || if ((g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) || g_img_replace_list)
(g_img_replace_list && g_img_replace_list->magic == GRUB_IMG_REPLACE_MAGIC))
{ {
ventoy_wrapper_push_openvolume(pFile->OpenVolume); ventoy_wrapper_push_openvolume(pFile->OpenVolume);
pFile->OpenVolume = ventoy_wrapper_open_volume; pFile->OpenVolume = ventoy_wrapper_open_volume;

View File

@ -98,7 +98,9 @@ typedef struct ventoy_os_param
UINT64 vtoy_reserved[4]; // Internal use by ventoy UINT64 vtoy_reserved[4]; // Internal use by ventoy
UINT8 reserved[31]; UINT8 vtoy_disk_signature[4];
UINT8 reserved[27];
}ventoy_os_param; }ventoy_os_param;
#pragma pack() #pragma pack()
@ -242,6 +244,7 @@ typedef int (*grub_env_printf_pf)(const char *fmt, ...);
#pragma pack(1) #pragma pack(1)
#define VTOY_MAX_CONF_REPLACE 2
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF #define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF #define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF
@ -268,7 +271,7 @@ typedef struct ventoy_grub_param
grub_env_get_pf grub_env_get; grub_env_get_pf grub_env_get;
grub_env_set_pf grub_env_set; grub_env_set_pf grub_env_set;
ventoy_grub_param_file_replace file_replace; ventoy_grub_param_file_replace file_replace;
ventoy_grub_param_file_replace img_replace; ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
grub_env_printf_pf grub_env_printf; grub_env_printf_pf grub_env_printf;
}ventoy_grub_param; }ventoy_grub_param;
@ -398,7 +401,7 @@ extern ventoy_virt_chunk *g_virt_chunk;
extern UINT32 g_virt_chunk_num; extern UINT32 g_virt_chunk_num;
extern vtoy_block_data gBlockData; extern vtoy_block_data gBlockData;
extern ventoy_efi_file_replace g_efi_file_replace; extern ventoy_efi_file_replace g_efi_file_replace;
extern ventoy_efi_file_replace g_img_file_replace; extern ventoy_efi_file_replace g_img_file_replace[VTOY_MAX_CONF_REPLACE];
extern ventoy_sector_flag *g_sector_flag; extern ventoy_sector_flag *g_sector_flag;
extern UINT32 g_sector_flag_num; extern UINT32 g_sector_flag_num;
extern BOOLEAN gMemdiskMode; extern BOOLEAN gMemdiskMode;

View File

@ -42,6 +42,7 @@
DebugLib DebugLib
[Guids] [Guids]
gEfiGlobalVariableGuid
gShellVariableGuid gShellVariableGuid
gEfiVirtualCdGuid gEfiVirtualCdGuid
gEfiFileInfoGuid gEfiFileInfoGuid

View File

@ -37,9 +37,6 @@
#include <Protocol/DriverBinding.h> #include <Protocol/DriverBinding.h>
#include <Ventoy.h> #include <Ventoy.h>
#define ASSIGN_REPLACE(This, replace) \
replace = (This->FlushEx == ventoy_wrapper_file_flush_ex) ? &g_efi_file_replace : &g_img_file_replace
UINT8 *g_iso_data_buf = NULL; UINT8 *g_iso_data_buf = NULL;
UINTN g_iso_buf_size = 0; UINTN g_iso_buf_size = 0;
BOOLEAN gMemdiskMode = FALSE; BOOLEAN gMemdiskMode = FALSE;
@ -155,7 +152,8 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
ventoy_override_chunk *pOverride = g_override_chunk; ventoy_override_chunk *pOverride = g_override_chunk;
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign); debug("read iso sector %lu count %u Buffer:%p Align:%u blk:%u",
Sector, Count, Buffer, pRawBlockIo->Media->IoAlign, pRawBlockIo->Media->BlockSize);
ReadStart = Sector * 2048; ReadStart = Sector * 2048;
ReadEnd = (Sector + Count) * 2048; ReadEnd = (Sector + Count) * 2048;
@ -1250,13 +1248,96 @@ ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
/* Ex version */ /* Ex version */
STATIC EFI_STATUS EFIAPI STATIC EFI_STATUS EFIAPI
ventoy_wrapper_file_flush_ex_img(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) ventoy_wrapper_file_flush_ex_img0(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
{
(VOID)This;
(VOID)Token;
return EFI_SUCCESS;
}
/* Ex version */
STATIC EFI_STATUS EFIAPI
ventoy_wrapper_file_flush_ex_img1(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
{ {
(VOID)This; (VOID)This;
(VOID)Token; (VOID)Token;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
#define DEF_WRAP_FUNC(n) \
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_flush_ex_img#n(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) \
{\
(VOID)This;\
(VOID)Token;\
return EFI_SUCCESS;\
}
#define ITEM_WRAP_FUNC(n) ventoy_wrapper_file_flush_ex_img#n
#if (VTOY_MAX_CONF_REPLACE > 2)
DEF_WRAP_FUNC(2);
#endif
#if (VTOY_MAX_CONF_REPLACE > 3)
DEF_WRAP_FUNC(3);
#endif
#if (VTOY_MAX_CONF_REPLACE > 4)
DEF_WRAP_FUNC(4);
#endif
#if (VTOY_MAX_CONF_REPLACE > 5)
DEF_WRAP_FUNC(5);
#endif
#if (VTOY_MAX_CONF_REPLACE > 6)
DEF_WRAP_FUNC(6);
#endif
#if (VTOY_MAX_CONF_REPLACE > 7)
DEF_WRAP_FUNC(7);
#endif
#if (VTOY_MAX_CONF_REPLACE > 8)
#error "VTOY_MAX_CONF_REPLACE overflow"
#endif
static EFI_FILE_FLUSH_EX g_img_flush_func[VTOY_MAX_CONF_REPLACE] =
{
ventoy_wrapper_file_flush_ex_img0,
ventoy_wrapper_file_flush_ex_img1,
#if (VTOY_MAX_CONF_REPLACE > 2)
ITEM_WRAP_FUNC(2),
#endif
#if (VTOY_MAX_CONF_REPLACE > 3)
ITEM_WRAP_FUNC(3),
#endif
#if (VTOY_MAX_CONF_REPLACE > 4)
ITEM_WRAP_FUNC(4),
#endif
#if (VTOY_MAX_CONF_REPLACE > 5)
ITEM_WRAP_FUNC(5),
#endif
#if (VTOY_MAX_CONF_REPLACE > 6)
ITEM_WRAP_FUNC(6),
#endif
#if (VTOY_MAX_CONF_REPLACE > 7)
ITEM_WRAP_FUNC(7),
#endif
};
STATIC ventoy_efi_file_replace *ventoy_wrapper_get_replace(EFI_FILE_HANDLE This)
{
UINTN i;
if (This->FlushEx == ventoy_wrapper_file_flush_ex)
{
return &g_efi_file_replace;
}
for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++)
{
if (This->FlushEx == g_img_flush_func[i])
{
return g_img_file_replace + i;
}
}
return NULL;
}
STATIC EFI_STATUS EFIAPI STATIC EFI_STATUS EFIAPI
ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
@ -1287,7 +1368,7 @@ ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
{ {
ventoy_efi_file_replace *replace = NULL; ventoy_efi_file_replace *replace = NULL;
ASSIGN_REPLACE(This, replace); replace = ventoy_wrapper_get_replace(This);
if (Position <= replace->FileSizeBytes) if (Position <= replace->FileSizeBytes)
{ {
@ -1306,7 +1387,7 @@ ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
{ {
ventoy_efi_file_replace *replace = NULL; ventoy_efi_file_replace *replace = NULL;
ASSIGN_REPLACE(This, replace); replace = ventoy_wrapper_get_replace(This);
*Position = replace->CurPos; *Position = replace->CurPos;
@ -1320,7 +1401,7 @@ ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, V
EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
ventoy_efi_file_replace *replace = NULL; ventoy_efi_file_replace *replace = NULL;
ASSIGN_REPLACE(This, replace); replace = ventoy_wrapper_get_replace(This);
debug("ventoy_wrapper_file_get_info ... %u", *Len); debug("ventoy_wrapper_file_get_info ... %u", *Len);
@ -1355,7 +1436,7 @@ ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
UINTN ReadLen = *Len; UINTN ReadLen = *Len;
ventoy_efi_file_replace *replace = NULL; ventoy_efi_file_replace *replace = NULL;
ASSIGN_REPLACE(This, replace); replace = ventoy_wrapper_get_replace(This);
debug("ventoy_wrapper_file_read ... %u", *Len); debug("ventoy_wrapper_file_read ... %u", *Len);
@ -1381,7 +1462,7 @@ ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN
return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer); return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
} }
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, BOOLEAN Img) STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, BOOLEAN Img, UINTN Index)
{ {
File->Revision = EFI_FILE_PROTOCOL_REVISION2; File->Revision = EFI_FILE_PROTOCOL_REVISION2;
File->Open = ventoy_wrapper_fs_open; File->Open = ventoy_wrapper_fs_open;
@ -1397,11 +1478,47 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, B
File->OpenEx = ventoy_wrapper_file_open_ex; File->OpenEx = ventoy_wrapper_file_open_ex;
File->ReadEx = ventoy_wrapper_file_read_ex; File->ReadEx = ventoy_wrapper_file_read_ex;
File->WriteEx = ventoy_wrapper_file_write_ex; File->WriteEx = ventoy_wrapper_file_write_ex;
File->FlushEx = Img ? ventoy_wrapper_file_flush_ex_img : ventoy_wrapper_file_flush_ex;
if (Img)
{
File->FlushEx = g_img_flush_func[Index];
}
else
{
File->FlushEx = ventoy_wrapper_file_flush_ex;
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
STATIC BOOLEAN EFIAPI ventoy_replace_name_match(CHAR8 *pReplace, CHAR8 *pName)
{
UINTN Len1, Len2;
Len1 = AsciiStrLen(pReplace);
Len2 = AsciiStrLen(pName);
if (Len1 == 0 || Len2 == 0)
{
return FALSE;
}
if (0 == AsciiStriCmp(pReplace, pName))
{
return TRUE;
}
if (Len1 > 2 && Len2 > 2)
{
if ((pReplace[0] != '\\') && (pName[0] == '\\') && (0 == AsciiStriCmp(pReplace, pName + 1)))
{
return TRUE;
}
}
return FALSE;
}
STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
( (
EFI_FILE_HANDLE This, EFI_FILE_HANDLE This,
@ -1418,6 +1535,7 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
CHAR8 TmpName[256]; CHAR8 TmpName[256];
CHAR8 OldName[256]; CHAR8 OldName[256];
ventoy_virt_chunk *virt = NULL; ventoy_virt_chunk *virt = NULL;
ventoy_grub_param_file_replace *replace = NULL;
debug("## ventoy_wrapper_file_open <%s> ", Name); debug("## ventoy_wrapper_file_open <%s> ", Name);
@ -1444,11 +1562,11 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
{ {
if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName)) if (ventoy_replace_name_match(g_file_replace_list[i].old_file_name[j], TmpName))
{ {
g_original_fclose(*New); g_original_fclose(*New);
*New = &g_efi_file_replace.WrapperHandle; *New = &g_efi_file_replace.WrapperHandle;
ventoy_wrapper_file_procotol(*New, FALSE); ventoy_wrapper_file_procotol(*New, FALSE, 0);
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id; virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
@ -1474,15 +1592,18 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
} }
} }
for (i = 0; g_img_replace_list && i < VTOY_MAX_CONF_REPLACE; i++)
if (g_img_replace_list && g_img_replace_list->magic == GRUB_IMG_REPLACE_MAGIC &&
g_img_replace_list->new_file_virtual_id < g_virt_chunk_num)
{ {
replace = g_img_replace_list + i;
if (replace->magic != GRUB_IMG_REPLACE_MAGIC || replace->new_file_virtual_id >= g_virt_chunk_num)
{
continue;
}
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
for (j = 0; j < g_img_replace_list->old_file_cnt; j++) for (j = 0; j < replace->old_file_cnt; j++)
{ {
AsciiStrCpyS(OldName, sizeof(OldName), g_img_replace_list[i].old_file_name[j]); AsciiStrCpyS(OldName, sizeof(OldName), replace->old_file_name[j]);
if ((0 == AsciiStrCmp(OldName, TmpName)) || if ((0 == AsciiStrCmp(OldName, TmpName)) ||
(AsciiStrnCmp(OldName, "\\loader\\entries\\", 16) == 0 && (AsciiStrnCmp(OldName, "\\loader\\entries\\", 16) == 0 &&
AsciiStrCmp(OldName + 16, TmpName) == 0 AsciiStrCmp(OldName + 16, TmpName) == 0
@ -1490,32 +1611,32 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
) )
{ {
g_original_fclose(*New); g_original_fclose(*New);
*New = &g_img_file_replace.WrapperHandle; *New = &(g_img_file_replace[i].WrapperHandle);
ventoy_wrapper_file_procotol(*New, TRUE); ventoy_wrapper_file_procotol(*New, TRUE, i);
virt = g_virt_chunk + g_img_replace_list->new_file_virtual_id; virt = g_virt_chunk + replace->new_file_virtual_id;
Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start); Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
g_img_file_replace.BlockIoSectorStart = virt->mem_sector_start; g_img_file_replace[i].BlockIoSectorStart = virt->mem_sector_start;
g_img_file_replace.FileSizeBytes = Sectors * 2048; g_img_file_replace[i].FileSizeBytes = Sectors * 2048;
if (gDebugPrint) if (gDebugPrint)
{ {
debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name, debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
g_img_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048); g_img_file_replace[i].BlockIoSectorStart, Sectors, Sectors * 2048);
sleep(3); sleep(3);
} }
return Status; return Status;
} }
} }
}
if (StrCmp(Name, L"\\loader\\entries") == 0) if (g_img_replace_list && StrCmp(Name, L"\\loader\\entries") == 0)
{ {
(*New)->Open = ventoy_wrapper_file_open; (*New)->Open = ventoy_wrapper_file_open;
} }
}
return Status; return Status;
} }

View File

@ -28,6 +28,8 @@ typedef int (*grub_env_set_pf)(const char *name, const char *val);
typedef const char * (*grub_env_get_pf)(const char *name); typedef const char * (*grub_env_get_pf)(const char *name);
typedef int (*grub_env_printf_pf)(const char *fmt, ...); typedef int (*grub_env_printf_pf)(const char *fmt, ...);
#define VTOY_MAX_CONF_REPLACE 2
typedef struct ventoy_grub_param_file_replace typedef struct ventoy_grub_param_file_replace
{ {
UINT32 magic; UINT32 magic;
@ -41,7 +43,7 @@ typedef struct ventoy_grub_param
grub_env_get_pf grub_env_get; grub_env_get_pf grub_env_get;
grub_env_set_pf grub_env_set; grub_env_set_pf grub_env_set;
ventoy_grub_param_file_replace file_replace; ventoy_grub_param_file_replace file_replace;
ventoy_grub_param_file_replace img_replace; ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
grub_env_printf_pf grub_env_printf; grub_env_printf_pf grub_env_printf;
}ventoy_grub_param; }ventoy_grub_param;
#pragma pack() #pragma pack()

View File

@ -913,6 +913,12 @@ module = {
enable = x86_64_efi; enable = x86_64_efi;
}; };
module = {
name = fwload;
efi = commands/efi/fwload.c;
enable = efi;
};
module = { module = {
name = gptsync; name = gptsync;
common = commands/gptsync.c; common = commands/gptsync.c;
@ -1123,6 +1129,21 @@ module = {
common = commands/sleep.c; common = commands/sleep.c;
}; };
module = {
name = smbios;
common = commands/smbios.c;
efi = commands/efi/smbios.c;
i386_pc = commands/i386/pc/smbios.c;
i386_coreboot = commands/i386/pc/smbios.c;
i386_multiboot = commands/i386/pc/smbios.c;
enable = efi;
enable = i386_pc;
enable = i386_coreboot;
enable = i386_multiboot;
};
module = { module = {
name = suspend; name = suspend;
ieee1275 = commands/ieee1275/suspend.c; ieee1275 = commands/ieee1275/suspend.c;
@ -1512,7 +1533,7 @@ module = {
name = squash4; name = squash4;
common = fs/squash4.c; common = fs/squash4.c;
cflags = '$(CFLAGS_POSIX) -Wno-undef'; cflags = '$(CFLAGS_POSIX) -Wno-undef';
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H';
}; };
module = { module = {
@ -1610,6 +1631,7 @@ module = {
common = ventoy/ventoy_vhd.c; common = ventoy/ventoy_vhd.c;
common = ventoy/ventoy_plugin.c; common = ventoy/ventoy_plugin.c;
common = ventoy/ventoy_json.c; common = ventoy/ventoy_json.c;
common = ventoy/ventoy_browser.c;
common = ventoy/lzx.c; common = ventoy/lzx.c;
common = ventoy/xpress.c; common = ventoy/xpress.c;
common = ventoy/huffman.c; common = ventoy/huffman.c;
@ -1621,6 +1643,12 @@ module = {
common = term/setkey.c; common = term/setkey.c;
}; };
module = {
name = mouse;
efi = term/efi/mouse.c;
enable = efi;
};
module = { module = {
name = hello; name = hello;
common = hello/hello.c; common = hello/hello.c;

View File

@ -0,0 +1,205 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 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/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/err.h>
#include <grub/extcmd.h>
#include <grub/file.h>
#include <grub/i18n.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
GRUB_MOD_LICENSE ("GPLv3+");
static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
static grub_efi_status_t
grub_efi_connect_all (void)
{
grub_efi_status_t status;
grub_efi_uintn_t handle_count;
grub_efi_handle_t *handle_buffer;
grub_efi_uintn_t index;
grub_efi_boot_services_t *b;
grub_dprintf ("efi", "Connecting ...\n");
b = grub_efi_system_table->boot_services;
status = efi_call_5 (b->locate_handle_buffer,
GRUB_EFI_ALL_HANDLES, NULL, NULL,
&handle_count, &handle_buffer);
if (status != GRUB_EFI_SUCCESS)
return status;
for (index = 0; index < handle_count; index++)
{
status = efi_call_4 (b->connect_controller,
handle_buffer[index], NULL, NULL, 1);
}
if (handle_buffer)
{
efi_call_1 (b->free_pool, handle_buffer);
}
return GRUB_EFI_SUCCESS;
}
static grub_err_t
grub_efi_load_driver (grub_size_t size, void *boot_image, int connect)
{
grub_efi_status_t status;
grub_efi_handle_t driver_handle;
grub_efi_boot_services_t *b;
grub_efi_loaded_image_t *loaded_image;
b = grub_efi_system_table->boot_services;
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, NULL,
boot_image, size, &driver_handle);
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
else
grub_error (GRUB_ERR_BAD_OS, "cannot load image");
goto fail;
}
loaded_image = grub_efi_get_loaded_image (driver_handle);
if (! loaded_image)
{
grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
goto fail;
}
grub_dprintf ("efi", "Registering loaded image\n");
status = efi_call_3 (b->handle_protocol, driver_handle,
&loaded_image_guid, (void **)&loaded_image);
if (status != GRUB_EFI_SUCCESS)
{
grub_error (GRUB_ERR_BAD_OS, "not a dirver");
goto fail;
}
grub_dprintf ("efi", "StartImage: %p\n", boot_image);
status = efi_call_3 (b->start_image, driver_handle, NULL, NULL);
if (status != GRUB_EFI_SUCCESS)
{
grub_error (GRUB_ERR_BAD_OS, "StartImage failed");
goto fail;
}
if (connect)
{
status = grub_efi_connect_all ();
if (status != GRUB_EFI_SUCCESS)
{
grub_error (GRUB_ERR_BAD_OS, "cannot connect controllers\n");
goto fail;
}
}
grub_dprintf ("efi", "Driver installed\n");
return 0;
fail:
return grub_errno;
}
static const struct grub_arg_option options_fwload[] =
{
{"nc", 'n', 0, N_("Loads the driver, but does not connect the driver."), 0, 0},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_fwload (grub_extcmd_context_t ctxt, int argc, char **args)
{
struct grub_arg_list *state = ctxt->state;
int connect = 1;
grub_file_t file = 0;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t pages = 0;
grub_ssize_t size;
grub_efi_physical_address_t address;
void *boot_image = 0;
b = grub_efi_system_table->boot_services;
if (argc != 1)
goto fail;
file = grub_file_open (args[0], GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
if (! file)
goto fail;
size = grub_file_size (file);
if (!size)
{
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
goto fail;
}
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
GRUB_EFI_LOADER_CODE, pages, &address);
if (status != GRUB_EFI_SUCCESS)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
goto fail;
}
boot_image = (void *) ((grub_addr_t) address);
if (grub_file_read (file, boot_image, size) != size)
{
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
goto fail;
}
grub_file_close (file);
if (state[0].set)
connect = 0;
if (grub_efi_load_driver (size, boot_image, connect))
goto fail;
return GRUB_ERR_NONE;
fail:
if (file)
grub_file_close (file);
if (address)
efi_call_2 (b->free_pages, address, pages);
return grub_errno;
}
static grub_err_t
grub_cmd_fwconnect (grub_extcmd_context_t ctxt __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_efi_connect_all ();
return GRUB_ERR_NONE;
}
static grub_extcmd_t cmd_fwload, cmd_fwconnect;
GRUB_MOD_INIT(fwload)
{
cmd_fwload = grub_register_extcmd ("fwload", grub_cmd_fwload, 0, N_("FILE"),
N_("Install UEFI driver."), options_fwload);
cmd_fwconnect = grub_register_extcmd ("fwconnect", grub_cmd_fwconnect, 0,
NULL, N_("Connect drivers."), 0);
}
GRUB_MOD_FINI(fwload)
{
grub_unregister_extcmd (cmd_fwload);
grub_unregister_extcmd (cmd_fwconnect);
}

View File

@ -0,0 +1,61 @@
/* smbios.c - get smbios tables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 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/smbios.h>
#include <grub/misc.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
struct grub_smbios_eps *
grub_machine_smbios_get_eps (void)
{
unsigned i;
static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_efi_packed_guid_t *guid =
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t)))
return (struct grub_smbios_eps *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
}
struct grub_smbios_eps3 *
grub_machine_smbios_get_eps3 (void)
{
unsigned i;
static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_efi_packed_guid_t *guid =
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t)))
return (struct grub_smbios_eps3 *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
}

View File

@ -260,6 +260,7 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
grub_file_t file; grub_file_t file;
grub_err_t err; grub_err_t err;
unsigned j; unsigned j;
int vlnk = 0;
file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: GRUB_FILE_TYPE_NONE)); : GRUB_FILE_TYPE_NONE));
@ -272,6 +273,7 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
unread++; unread++;
continue; continue;
} }
vlnk = file->vlnk;
err = hash_file (file, hash, result); err = hash_file (file, hash, result);
grub_file_close (file); grub_file_close (file);
if (err) if (err)
@ -288,7 +290,7 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
grub_printf ("%02x", ((grub_uint8_t *) result)[j]); grub_printf ("%02x", ((grub_uint8_t *) result)[j]);
len += grub_snprintf(hashsum + len, sizeof(hashsum) - len, "%02x", ((grub_uint8_t *) result)[j]); len += grub_snprintf(hashsum + len, sizeof(hashsum) - len, "%02x", ((grub_uint8_t *) result)[j]);
} }
grub_printf (" %s\n", args[i]); grub_printf (" %s\n", vlnk ? grub_file_get_vlnk(args[i], NULL) : args[i]);
grub_env_set("VT_LAST_CHECK_SUM", hashsum); grub_env_set("VT_LAST_CHECK_SUM", hashsum);
} }

View File

@ -0,0 +1,52 @@
/* smbios.c - get smbios tables. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 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/acpi.h>
#include <grub/smbios.h>
#include <grub/misc.h>
struct grub_smbios_eps *
grub_machine_smbios_get_eps (void)
{
grub_uint8_t *ptr;
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
if (grub_memcmp (ptr, "_SM_", 4) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
return (struct grub_smbios_eps *) ptr;
return 0;
}
struct grub_smbios_eps3 *
grub_machine_smbios_get_eps3 (void)
{
grub_uint8_t *ptr;
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
if (grub_memcmp (ptr, "_SM3_", 5) == 0
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
return (struct grub_smbios_eps3 *) ptr;
return 0;
}

View File

@ -68,7 +68,7 @@ iterate_device (const char *name, void *data)
/* Skip floppy drives when requested. */ /* Skip floppy drives when requested. */
if (ctx->no_floppy && if (ctx->no_floppy &&
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
return 1; return 0;
if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) { if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) {
return 0; return 0;

View File

@ -0,0 +1,399 @@
/* smbios.c - retrieve smbios information. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 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/env.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/smbios.h>
GRUB_MOD_LICENSE ("GPLv3+");
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
static struct {
grub_addr_t start;
grub_addr_t end;
grub_uint16_t structures;
} table_desc;
static grub_extcmd_t cmd;
/* Locate the SMBIOS entry point structure depending on the hardware. */
struct grub_smbios_eps *
grub_smbios_get_eps (void)
{
static struct grub_smbios_eps *eps = NULL;
if (eps != NULL)
return eps;
eps = grub_machine_smbios_get_eps ();
return eps;
}
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
static struct grub_smbios_eps3 *
grub_smbios_get_eps3 (void)
{
static struct grub_smbios_eps3 *eps = NULL;
if (eps != NULL)
return eps;
eps = grub_machine_smbios_get_eps3 ();
return eps;
}
static char *
linux_string (const char *value)
{
char *out = grub_malloc( grub_strlen (value) + 1);
const char *src = value;
char *dst = out;
for (; *src; src++)
if (*src > ' ' && *src < 127 && *src != ':')
*dst++ = *src;
*dst = 0;
return out;
}
/*
* These functions convert values from the various SMBIOS structure field types
* into a string formatted to be returned to the user. They expect that the
* structure and offset were already validated. When the requested data is
* successfully retrieved and formatted, the pointer to the string is returned;
* otherwise, NULL is returned on failure. Don't free the result.
*/
static const char *
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
{
static char buffer[sizeof ("255")];
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
return (const char *)buffer;
}
static const char *
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
{
static char buffer[sizeof ("65535")];
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
grub_snprintf (buffer, sizeof (buffer), "%u", value);
return (const char *)buffer;
}
static const char *
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
{
static char buffer[sizeof ("4294967295")];
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
return (const char *)buffer;
}
static const char *
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
{
static char buffer[sizeof ("18446744073709551615")];
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
return (const char *)buffer;
}
static const char *
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
{
const grub_uint8_t *ptr = structure + structure[1];
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
const grub_uint8_t referenced_string_number = structure[offset];
grub_uint8_t i;
/* A string referenced with zero is interpreted as unset. */
if (referenced_string_number == 0)
return NULL;
/* Search the string set. */
for (i = 1; *ptr != 0 && ptr < table_end; i++)
if (i == referenced_string_number)
{
const char *str = (const char *)ptr;
while (*ptr++ != 0)
if (ptr >= table_end)
return NULL; /* The string isn't terminated. */
return str;
}
else
while (*ptr++ != 0 && ptr < table_end);
/* The string number is greater than the number of strings in the set. */
return NULL;
}
static const char *
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
{
static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")];
const grub_uint8_t *f = structure + offset; /* little-endian fields */
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
grub_snprintf (buffer, sizeof (buffer),
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
return (const char *)buffer;
}
/* List the field formatting functions and the number of bytes they need. */
static const struct {
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
grub_uint8_t field_length;
} field_extractors[] = {
{grub_smbios_format_byte, 1},
{grub_smbios_format_word, 2},
{grub_smbios_format_dword, 4},
{grub_smbios_format_qword, 8},
{grub_smbios_get_string, 1},
{grub_smbios_format_uuid, 16}
};
/* List command options, with structure field getters ordered as above. */
#define FIRST_GETTER_OPT (3)
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1)
static const struct grub_arg_option options[] = {
{"type", 't', 0, N_("Match structures with the given type."),
N_("type"), ARG_TYPE_INT},
{"handle", 'h', 0, N_("Match structures with the given handle."),
N_("handle"), ARG_TYPE_INT},
{"match", 'm', 0, N_("Select a structure when several match."),
N_("match"), ARG_TYPE_INT},
{"get-byte", 'b', 0, N_("Get the byte's value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-word", 'w', 0, N_("Get two bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-string", 's', 0, N_("Get the string specified at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."),
N_("offset"), ARG_TYPE_INT},
{"set", '\0', 0, N_("Store the value in the given variable name."),
N_("variable"), ARG_TYPE_STRING},
{"linux", '\0', 0, N_("Filter the result like linux does."),
N_("variable"), ARG_TYPE_NONE},
{0, 0, 0, 0, 0, 0}
};
/*
* Return a matching SMBIOS structure.
*
* This method can use up to three criteria for selecting a structure:
* - The "type" field (use -1 to ignore)
* - The "handle" field (use -1 to ignore)
* - Which to return if several match (use 0 to ignore)
*
* The return value is a pointer to the first matching structure. If no
* structures match the given parameters, NULL is returned.
*/
static const grub_uint8_t *
grub_smbios_match_structure (const grub_int16_t type,
const grub_int32_t handle,
const grub_uint16_t match)
{
const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start;
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
grub_uint16_t structures = table_desc.structures;
grub_uint16_t structure_count = 0;
grub_uint16_t matches = 0;
while (ptr < table_end
&& ptr[1] >= 4 /* Valid structures include the 4-byte header. */
&& (structure_count++ < structures || structures == 0))
{
grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2);
grub_uint8_t structure_type = ptr[0];
if ((handle < 0 || handle == structure_handle)
&& (type < 0 || type == structure_type)
&& (match == 0 || match == ++matches))
return ptr;
else
{
ptr += ptr[1];
while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end);
}
if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE)
break;
}
return NULL;
}
static grub_err_t
grub_cmd_smbios (grub_extcmd_context_t ctxt,
int argc __attribute__ ((unused)),
char **argv __attribute__ ((unused)))
{
struct grub_arg_list *state = ctxt->state;
grub_int16_t type = -1;
grub_int32_t handle = -1;
grub_uint16_t match = 0;
grub_uint8_t offset = 0;
const grub_uint8_t *structure;
const char *value;
char *modified_value = NULL;
grub_int32_t option;
grub_int8_t field_type = -1;
grub_uint8_t i;
if (table_desc.start == 0)
return grub_error (GRUB_ERR_IO,
N_("the SMBIOS entry point structure was not found"));
/* Read the given filtering options. */
if (state[0].set)
{
option = grub_strtol (state[0].arg, NULL, 0);
if (option < 0 || option > 255)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the type must be between 0 and 255"));
type = (grub_int16_t)option;
}
if (state[1].set)
{
option = grub_strtol (state[1].arg, NULL, 0);
if (option < 0 || option > 65535)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the handle must be between 0 and 65535"));
handle = (grub_int32_t)option;
}
if (state[2].set)
{
option = grub_strtol (state[2].arg, NULL, 0);
if (option <= 0 || option > 65535)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("the match must be a positive integer"));
match = (grub_uint16_t)option;
}
/* Determine the data type of the structure field to retrieve. */
for (i = 0; i < ARRAY_SIZE(field_extractors); i++)
if (state[FIRST_GETTER_OPT + i].set)
{
if (field_type >= 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("only one --get option is usable at a time"));
field_type = i;
}
/* Require a choice of a structure field to return. */
if (field_type < 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("one of the --get options is required"));
/* Locate a matching SMBIOS structure. */
structure = grub_smbios_match_structure (type, handle, match);
if (structure == NULL)
return grub_error (GRUB_ERR_IO,
N_("no structure matched the given options"));
/* Ensure the requested byte offset is inside the structure. */
option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0);
if (option < 0 || option >= structure[1])
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("the given offset is outside the structure"));
/* Ensure the requested data type at the offset is inside the structure. */
offset = (grub_uint8_t)option;
if (offset + field_extractors[field_type].field_length > structure[1])
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("the field ends outside the structure"));
/* Format the requested structure field into a readable string. */
value = field_extractors[field_type].format (structure, offset);
if (value == NULL)
return grub_error (GRUB_ERR_IO,
N_("failed to retrieve the structure field"));
if (state[LINUX_OPT].set)
value = modified_value = linux_string (value);
/* Store or print the formatted value. */
if (state[SETTER_OPT].set)
grub_env_set (state[SETTER_OPT].arg, value);
else
grub_printf ("%s\n", value);
grub_free(modified_value);
return GRUB_ERR_NONE;
}
GRUB_MOD_INIT(smbios)
{
struct grub_smbios_eps3 *eps3;
struct grub_smbios_eps *eps;
if ((eps3 = grub_smbios_get_eps3 ()))
{
table_desc.start = (grub_addr_t)eps3->table_address;
table_desc.end = table_desc.start + eps3->maximum_table_length;
table_desc.structures = 0; /* SMBIOS3 drops the structure count. */
}
else if ((eps = grub_smbios_get_eps ()))
{
table_desc.start = (grub_addr_t)eps->intermediate.table_address;
table_desc.end = table_desc.start + eps->intermediate.table_length;
table_desc.structures = eps->intermediate.structures;
}
cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0,
N_("[-t type] [-h handle] [-m match] "
"(-b|-w|-d|-q|-s|-u) offset "
"[--set variable]"),
N_("Retrieve SMBIOS information."), options);
}
GRUB_MOD_FINI(smbios)
{
grub_unregister_extcmd (cmd);
}

View File

@ -229,6 +229,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-EQ") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
== grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-ge") == 0) if (grub_strcmp (args[*argn + 1], "-ge") == 0)
{ {
@ -237,6 +244,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-GE") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
>= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-gt") == 0) if (grub_strcmp (args[*argn + 1], "-gt") == 0)
{ {
@ -245,6 +259,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-GT") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
> grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-le") == 0) if (grub_strcmp (args[*argn + 1], "-le") == 0)
{ {
@ -253,6 +274,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-LE") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
<= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-lt") == 0) if (grub_strcmp (args[*argn + 1], "-lt") == 0)
{ {
@ -261,6 +289,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-LT") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
< grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-ne") == 0) if (grub_strcmp (args[*argn + 1], "-ne") == 0)
{ {
@ -269,6 +304,13 @@ test_parse (char **args, int *argn, int argc)
(*argn) += 3; (*argn) += 3;
continue; continue;
} }
if (grub_strcmp (args[*argn + 1], "-NE") == 0)
{
update_val (grub_strtoull (args[*argn], 0, 0)
!= grub_strtoull (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
/* GRUB extension: compare numbers skipping prefixes. /* GRUB extension: compare numbers skipping prefixes.
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */ Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */

View File

@ -103,6 +103,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000
#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
/* The set of back-incompatible features this driver DOES support. Add (OR) /* The set of back-incompatible features this driver DOES support. Add (OR)
@ -123,9 +124,16 @@ GRUB_MOD_LICENSE ("GPLv3+");
* mmp: Not really back-incompatible - was added as such to * mmp: Not really back-incompatible - was added as such to
* avoid multiple read-write mounts. Safe to ignore for this * avoid multiple read-write mounts. Safe to ignore for this
* RO driver. * RO driver.
* checksum seed: Not really back-incompatible - was added to allow tools
* such as tune2fs to change the UUID on a mounted metadata
* checksummed filesystem. Safe to ignore for now since the
* driver doesn't support checksum verification. But it must
* be removed from this list if that support is added later.
*
*/ */
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \ #define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
| EXT4_FEATURE_INCOMPAT_MMP) | EXT4_FEATURE_INCOMPAT_MMP \
| EXT4_FEATURE_INCOMPAT_CSUM_SEED)
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U #define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
@ -723,10 +731,11 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
if (! symlink) if (! symlink)
return 0; return 0;
/* If the filesize of the symlink is bigger than /*
60 the symlink is stored in a separate block, * If the filesize of the symlink is equal to or bigger than 60 the symlink
otherwise it is stored in the inode. */ * is stored in a separate block, otherwise it is stored in the inode.
if (grub_le_to_cpu32 (diro->inode.size) <= sizeof (diro->inode.symlink)) */
if (grub_le_to_cpu32 (diro->inode.size) < sizeof (diro->inode.symlink))
grub_memcpy (symlink, grub_memcpy (symlink,
diro->inode.symlink, diro->inode.symlink,
grub_le_to_cpu32 (diro->inode.size)); grub_le_to_cpu32 (diro->inode.size));

View File

@ -426,7 +426,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
if (grub_errno) if (grub_errno)
return -1; return -1;
} }
else if (read_hook != (grub_disk_read_hook_t)grub_disk_blocklist_read) else if (read_hook != (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read)
grub_memset (buf, 0, blockend); grub_memset (buf, 0, blockend);
buf += blocksize - skipfirst; buf += blocksize - skipfirst;

View File

@ -889,6 +889,7 @@ grub_ntfs_mount (grub_disk_t disk)
struct grub_ntfs_bpb bpb; struct grub_ntfs_bpb bpb;
struct grub_ntfs_data *data = 0; struct grub_ntfs_data *data = 0;
grub_uint32_t spc; grub_uint32_t spc;
grub_uint32_t sectors_per_cluster;
if (!disk) if (!disk)
goto fail; goto fail;
@ -903,14 +904,18 @@ grub_ntfs_mount (grub_disk_t disk)
if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
goto fail; goto fail;
sectors_per_cluster = bpb.sectors_per_cluster;
if (sectors_per_cluster > 0x80)
sectors_per_cluster = 1U << (256U - bpb.sectors_per_cluster);
if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0 if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0
|| bpb.sectors_per_cluster == 0 || sectors_per_cluster == 0
|| (bpb.sectors_per_cluster & (bpb.sectors_per_cluster - 1)) != 0 || (sectors_per_cluster & (sectors_per_cluster - 1)) != 0
|| bpb.bytes_per_sector == 0 || bpb.bytes_per_sector == 0
|| (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0) || (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0)
goto fail; goto fail;
spc = (((grub_uint32_t) bpb.sectors_per_cluster spc = (((grub_uint32_t) sectors_per_cluster
* (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector))
>> GRUB_NTFS_BLK_SHR); >> GRUB_NTFS_BLK_SHR);
if (spc == 0) if (spc == 0)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,285 @@
/*
* LZ4 - Fast LZ compression algorithm
* Header File
* Copyright (C) 2011-2013, Yann Collet.
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You can contact the author at :
* - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
* - LZ4 source repository : http://code.google.com/p/lz4/
*/
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/types.h>
int LZ4_uncompress_unknownOutputSize(const char *source, char *dest,
int isize, int maxOutputSize);
/*
* CPU Feature Detection
*/
/* 32 or 64 bits ? */
#if (GRUB_CPU_SIZEOF_VOID_P == 8)
#define LZ4_ARCH64 1
#else
#define LZ4_ARCH64 0
#endif
/*
* Compiler Options
*/
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#if (GCC_VERSION >= 302) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 800) || defined(__clang__)
#define expect(expr, value) (__builtin_expect((expr), (value)))
#else
#define expect(expr, value) (expr)
#endif
#define likely(expr) expect((expr) != 0, 1)
#define unlikely(expr) expect((expr) != 0, 0)
/* Basic types */
#define BYTE grub_uint8_t
#define U16 grub_uint16_t
#define U32 grub_uint32_t
#define S32 grub_int32_t
#define U64 grub_uint64_t
typedef struct _U16_S {
U16 v;
} GRUB_PACKED U16_S;
typedef struct _U32_S {
U32 v;
} GRUB_PACKED U32_S;
typedef struct _U64_S {
U64 v;
} GRUB_PACKED U64_S;
#define A64(x) (((U64_S *)(x))->v)
#define A32(x) (((U32_S *)(x))->v)
#define A16(x) (((U16_S *)(x))->v)
/*
* Constants
*/
#define MINMATCH 4
#define COPYLENGTH 8
#define LASTLITERALS 5
#define ML_BITS 4
#define ML_MASK ((1U<<ML_BITS)-1)
#define RUN_BITS (8-ML_BITS)
#define RUN_MASK ((1U<<RUN_BITS)-1)
/*
* Architecture-specific macros
*/
#if LZ4_ARCH64
#define STEPSIZE 8
#define UARCH U64
#define AARCH A64
#define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8;
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d)
#define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e)
#define HTYPE U32
#define INITBASE(base) const BYTE* const base = ip
#else
#define STEPSIZE 4
#define UARCH U32
#define AARCH A32
#define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4;
#define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d);
#define LZ4_SECURECOPY LZ4_WILDCOPY
#define HTYPE const BYTE*
#define INITBASE(base) const int base = 0
#endif
#define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - grub_le_to_cpu16 (A16 (p)); }
#define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = grub_cpu_to_le16 (v); p += 2; }
/* Macros */
#define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e);
/* Decompression functions */
grub_err_t
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len);
grub_err_t
lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len)
{
const BYTE *src = s_start;
U32 bufsiz = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) |
src[3];
/* invalid compressed buffer size encoded at start */
if (bufsiz + 4 > s_len)
return grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed.");
/*
* Returns 0 on success (decompression function returned non-negative)
* and appropriate error on failure (decompression function returned negative).
*/
return (LZ4_uncompress_unknownOutputSize((char*)s_start + 4, d_start, bufsiz,
d_len) < 0)?grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."):0;
}
int
LZ4_uncompress_unknownOutputSize(const char *source,
char *dest, int isize, int maxOutputSize)
{
/* Local Variables */
const BYTE * ip = (const BYTE *) source;
const BYTE *const iend = ip + isize;
const BYTE * ref;
BYTE * op = (BYTE *) dest;
BYTE *const oend = op + maxOutputSize;
BYTE *cpy;
grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 };
/* Main Loop */
while (ip < iend) {
BYTE token;
int length;
/* get runlength */
token = *ip++;
if ((length = (token >> ML_BITS)) == RUN_MASK) {
int s = 255;
while ((ip < iend) && (s == 255)) {
s = *ip++;
length += s;
}
}
/* copy literals */
if ((grub_addr_t) length > ~(grub_addr_t)op)
goto _output_error;
cpy = op + length;
if ((cpy > oend - COPYLENGTH) ||
(ip + length > iend - COPYLENGTH)) {
if (cpy > oend)
/*
* Error: request to write beyond destination
* buffer.
*/
goto _output_error;
if (ip + length > iend)
/*
* Error : request to read beyond source
* buffer.
*/
goto _output_error;
grub_memcpy(op, ip, length);
op += length;
ip += length;
if (ip < iend)
/* Error : LZ4 format violation */
goto _output_error;
/* Necessarily EOF, due to parsing restrictions. */
break;
}
LZ4_WILDCOPY(ip, op, cpy);
ip -= (op - cpy);
op = cpy;
/* get offset */
LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip);
ip += 2;
if (ref < (BYTE * const) dest)
/*
* Error: offset creates reference outside of
* destination buffer.
*/
goto _output_error;
/* get matchlength */
if ((length = (token & ML_MASK)) == ML_MASK) {
while (ip < iend) {
int s = *ip++;
length += s;
if (s == 255)
continue;
break;
}
}
/* copy repeated sequence */
if unlikely(op - ref < STEPSIZE) {
#if LZ4_ARCH64
grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
grub_size_t dec2 = dec2table[op - ref];
#else
const int dec2 = 0;
#endif
*op++ = *ref++;
*op++ = *ref++;
*op++ = *ref++;
*op++ = *ref++;
ref -= dec[op - ref];
A32(op) = A32(ref);
op += STEPSIZE - 4;
ref -= dec2;
} else {
LZ4_COPYSTEP(ref, op);
}
cpy = op + length - (STEPSIZE - 4);
if (cpy > oend - COPYLENGTH) {
if (cpy > oend)
/*
* Error: request to write outside of
* destination buffer.
*/
goto _output_error;
LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH));
while (op < cpy)
*op++ = *ref++;
op = cpy;
if (op == oend)
/*
* Check EOF (should never happen, since last
* 5 bytes are supposed to be literals).
*/
break;
continue;
}
LZ4_SECURECOPY(ref, op, cpy);
op = cpy; /* correction */
}
/* end of decoding */
return (int)(((char *)op) - dest);
/* write overflow error detected */
_output_error:
return (int)(-(((char *)ip) - source));
}

View File

@ -119,6 +119,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
view->menu = menu; view->menu = menu;
view->nested = nested; view->nested = nested;
view->first_timeout = -1; view->first_timeout = -1;
if (menu->size)
view->menu_title_offset = grub_zalloc (sizeof (*view->menu_title_offset) * menu->size);
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
if (view->double_repaint) if (view->double_repaint)
@ -134,6 +136,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
instance->fini = grub_gfxmenu_viewer_fini; instance->fini = grub_gfxmenu_viewer_fini;
instance->print_timeout = grub_gfxmenu_print_timeout; instance->print_timeout = grub_gfxmenu_print_timeout;
instance->clear_timeout = grub_gfxmenu_clear_timeout; instance->clear_timeout = grub_gfxmenu_clear_timeout;
if (view->menu_title_offset)
instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry;
grub_menu_register_viewer (instance); grub_menu_register_viewer (instance);

View File

@ -31,6 +31,7 @@ extern int g_ventoy_iso_raw;
extern int g_ventoy_grub2_mode; extern int g_ventoy_grub2_mode;
extern int g_ventoy_wimboot_mode; extern int g_ventoy_wimboot_mode;
extern int g_ventoy_iso_uefi_drv; extern int g_ventoy_iso_uefi_drv;
extern char g_ventoy_hotkey_tip[256];
static const char *align_options[] = static const char *align_options[] =
{ {
@ -230,10 +231,11 @@ label_set_property (void *vself, const char *name, const char *value)
value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " "; value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
} }
else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) { else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
value = grub_env_get("VTOY_HOTKEY_TIP"); value = g_ventoy_hotkey_tip;
if (value == NULL) { } else if (value[0] == '@' && value[1] == '@' && value[2]) {
value = _(" "); value = grub_env_get(value + 2);
} if (!value)
value = " ";
} }
self->template = grub_strdup (value); self->template = grub_strdup (value);

View File

@ -0,0 +1,961 @@
/* gui_list.c - GUI component to display a selectable list of items. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/gui.h>
#include <grub/gui_string_util.h>
#include <grub/gfxmenu_view.h>
#include <grub/gfxwidgets.h>
#include <grub/color.h>
#include <grub/charset.h>
enum scrollbar_slice_mode {
SCROLLBAR_SLICE_WEST,
SCROLLBAR_SLICE_CENTER,
SCROLLBAR_SLICE_EAST
};
struct grub_gui_list_impl
{
struct grub_gui_list list;
grub_gui_container_t parent;
grub_video_rect_t bounds;
char *id;
int visible;
int icon_width;
int icon_height;
int item_height;
int item_padding;
int item_icon_space;
int item_spacing;
grub_font_t item_font;
int selected_item_font_inherit;
grub_font_t selected_item_font;
grub_video_rgba_color_t item_color;
int selected_item_color_inherit;
grub_video_rgba_color_t selected_item_color;
int draw_scrollbar;
int need_to_recreate_scrollbar;
char *scrollbar_frame_pattern;
char *scrollbar_thumb_pattern;
grub_gfxmenu_box_t scrollbar_frame;
grub_gfxmenu_box_t scrollbar_thumb;
int scrollbar_thumb_overlay;
int scrollbar_width;
enum scrollbar_slice_mode scrollbar_slice;
int scrollbar_left_pad;
int scrollbar_right_pad;
int scrollbar_top_pad;
int scrollbar_bottom_pad;
int first_shown_index;
int need_to_recreate_boxes;
char *theme_dir;
char *menu_box_pattern;
char *item_box_pattern;
int selected_item_box_pattern_inherit;
char *selected_item_box_pattern;
grub_gfxmenu_box_t menu_box;
grub_gfxmenu_box_t selected_item_box;
grub_gfxmenu_box_t item_box;
grub_gfxmenu_icon_manager_t icon_manager;
grub_gfxmenu_view_t view;
};
typedef struct grub_gui_list_impl *list_impl_t;
static void
list_destroy (void *vself)
{
list_impl_t self = vself;
grub_free (self->theme_dir);
grub_free (self->menu_box_pattern);
grub_free (self->item_box_pattern);
grub_free (self->selected_item_box_pattern);
if (self->menu_box)
self->menu_box->destroy (self->menu_box);
if (self->item_box)
self->item_box->destroy (self->item_box);
if (self->selected_item_box)
self->selected_item_box->destroy (self->selected_item_box);
if (self->icon_manager)
grub_gfxmenu_icon_manager_destroy (self->icon_manager);
if (self->scrollbar_thumb)
self->scrollbar_thumb->destroy (self->scrollbar_thumb);
if (self->scrollbar_frame)
self->scrollbar_frame->destroy (self->scrollbar_frame);
grub_free (self->scrollbar_thumb_pattern);
grub_free (self->scrollbar_frame_pattern);
grub_free (self);
}
static int
get_num_shown_items (list_impl_t self)
{
int boxpad = self->item_padding;
int item_vspace = self->item_spacing;
int item_height = self->item_height;
grub_gfxmenu_box_t box = self->menu_box;
int box_top_pad = box->get_top_pad (box);
int box_bottom_pad = box->get_bottom_pad (box);
grub_gfxmenu_box_t itembox = self->item_box;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int item_top_pad = itembox->get_top_pad (itembox);
int item_bottom_pad = itembox->get_bottom_pad (itembox);
int sel_top_pad = selbox->get_top_pad (selbox);
int sel_bottom_pad = selbox->get_bottom_pad (selbox);
int max_top_pad = grub_max (item_top_pad, sel_top_pad);
int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad);
if (item_height + item_vspace <= 0)
return 1;
return (self->bounds.height + item_vspace - 2 * boxpad
- max_top_pad - max_bottom_pad
- box_top_pad - box_bottom_pad) / (item_height + item_vspace);
}
static int
check_boxes (list_impl_t self)
{
if (self->need_to_recreate_boxes)
{
grub_gui_recreate_box (&self->menu_box,
self->menu_box_pattern,
self->theme_dir);
grub_gui_recreate_box (&self->item_box,
self->item_box_pattern,
self->theme_dir);
grub_gui_recreate_box (&self->selected_item_box,
self->selected_item_box_pattern,
self->theme_dir);
self->need_to_recreate_boxes = 0;
}
return (self->menu_box != 0 && self->selected_item_box != 0
&& self->item_box != 0);
}
static int
check_scrollbar (list_impl_t self)
{
if (self->need_to_recreate_scrollbar)
{
grub_gui_recreate_box (&self->scrollbar_frame,
self->scrollbar_frame_pattern,
self->theme_dir);
grub_gui_recreate_box (&self->scrollbar_thumb,
self->scrollbar_thumb_pattern,
self->theme_dir);
self->need_to_recreate_scrollbar = 0;
}
if (self->scrollbar_frame == 0 || self->scrollbar_thumb == 0)
return 0;
/* Sanity checks. */
grub_gfxmenu_box_t frame = self->scrollbar_frame;
grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
grub_gfxmenu_box_t menu = self->menu_box;
int min_width = frame->get_left_pad (frame)
+ frame->get_right_pad (frame);
int min_height = frame->get_top_pad (frame)
+ frame->get_bottom_pad (frame)
+ self->scrollbar_top_pad + self->scrollbar_bottom_pad
+ menu->get_top_pad (menu)
+ menu->get_bottom_pad (menu);
if (!self->scrollbar_thumb_overlay)
{
min_width += thumb->get_left_pad (thumb)
+ thumb->get_right_pad (thumb);
min_height += thumb->get_top_pad (thumb)
+ thumb->get_bottom_pad (thumb);
}
if (min_width <= self->scrollbar_width
&& min_height <= (int) self->bounds.height)
return 1;
/* Unprintable dimenstions. */
self->draw_scrollbar = 0;
return 0;
}
static const char *
list_get_id (void *vself)
{
list_impl_t self = vself;
return self->id;
}
static int
list_is_instance (void *vself __attribute__((unused)), const char *type)
{
return (grub_strcmp (type, "component") == 0
|| grub_strcmp (type, "list") == 0);
}
static struct grub_video_bitmap *
get_item_icon (list_impl_t self, int item_index)
{
grub_menu_entry_t entry;
entry = grub_menu_get_entry (self->view->menu, item_index);
if (! entry)
return 0;
return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry);
}
static void
make_selected_item_visible (list_impl_t self)
{
int selected_index = self->view->selected;
if (selected_index < 0)
return; /* No item is selected. */
int num_shown_items = get_num_shown_items (self);
int last_shown_index = self->first_shown_index + (num_shown_items - 1);
if (selected_index < self->first_shown_index)
self->first_shown_index = selected_index;
else if (selected_index > last_shown_index)
self->first_shown_index = selected_index - (num_shown_items - 1);
}
/* Draw a scrollbar on the menu. */
static void
draw_scrollbar (list_impl_t self,
int value, int extent, int min, int max,
int scrollbar_width, int scrollbar_height)
{
unsigned thumby, thumbheight;
grub_gfxmenu_box_t frame = self->scrollbar_frame;
grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
int frame_vertical_pad = (frame->get_top_pad (frame)
+ frame->get_bottom_pad (frame));
int frame_horizontal_pad = (frame->get_left_pad (frame)
+ frame->get_right_pad (frame));
unsigned thumb_vertical_pad = (thumb->get_top_pad (thumb)
+ thumb->get_bottom_pad (thumb));
int thumb_horizontal_pad = (thumb->get_left_pad (thumb)
+ thumb->get_right_pad (thumb));
int tracktop = frame->get_top_pad (frame);
unsigned tracklen;
if (scrollbar_height <= frame_vertical_pad)
tracklen = 0;
else
tracklen = scrollbar_height - frame_vertical_pad;
frame->set_content_size (frame,
scrollbar_width - frame_horizontal_pad,
tracklen);
if (self->scrollbar_thumb_overlay)
{
tracklen += thumb_vertical_pad;
tracktop -= thumb->get_top_pad (thumb);
}
if (value <= min || max <= min)
thumby = 0;
else
thumby = ((unsigned) tracklen * (value - min))
/ ((unsigned) (max - min));
if (max <= min)
thumbheight = 1;
else
thumbheight = ((unsigned) (tracklen * extent)
/ ((unsigned) (max - min))) + 1;
/* Rare occasion: too many entries or too low height. */
if (thumbheight < thumb_vertical_pad)
{
thumbheight = thumb_vertical_pad;
if (value <= min || max <= extent
|| tracklen <= thumb_vertical_pad)
thumby = 0;
else
thumby = ((unsigned) ((tracklen - thumb_vertical_pad) * (value - min))
/ ((unsigned)(max - extent)));
}
thumby += tracktop;
int thumbx = frame->get_left_pad (frame);
int thumbwidth = scrollbar_width - frame_horizontal_pad;
if (!self->scrollbar_thumb_overlay)
thumbwidth -= thumb_horizontal_pad;
else
thumbx -= thumb->get_left_pad (thumb);
thumb->set_content_size (thumb, thumbwidth,
thumbheight - thumb_vertical_pad);
frame->draw (frame, 0, 0);
thumb->draw (thumb, thumbx, thumby);
}
/* Draw the list of items. */
static void
draw_menu (list_impl_t self, int num_shown_items)
{
if (! self->menu_box || ! self->selected_item_box || ! self->item_box)
return;
int boxpad = self->item_padding;
int icon_text_space = self->item_icon_space;
int item_vspace = self->item_spacing;
int ascent = grub_font_get_ascent (self->item_font);
int descent = grub_font_get_descent (self->item_font);
int selected_ascent = grub_font_get_ascent (self->selected_item_font);
int selected_descent = grub_font_get_descent (self->selected_item_font);
int text_box_height = self->item_height;
make_selected_item_visible (self);
grub_gfxmenu_box_t itembox = self->item_box;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int item_leftpad = itembox->get_left_pad (itembox);
int item_rightpad = itembox->get_right_pad (itembox);
int item_border_width = item_leftpad + item_rightpad;
int item_toppad = itembox->get_top_pad (itembox);
int sel_leftpad = selbox->get_left_pad (selbox);
int sel_rightpad = selbox->get_right_pad (selbox);
int sel_border_width = sel_leftpad + sel_rightpad;
int sel_toppad = selbox->get_top_pad (selbox);
int max_leftpad = grub_max (item_leftpad, sel_leftpad);
int max_toppad = grub_max (item_toppad, sel_toppad);
int item_top = 0;
int menu_index;
int visible_index;
struct grub_video_rect oviewport;
grub_video_get_viewport (&oviewport.x, &oviewport.y,
&oviewport.width, &oviewport.height);
grub_video_set_viewport (oviewport.x + boxpad,
oviewport.y + boxpad,
oviewport.width - 2 * boxpad,
oviewport.height - 2 * boxpad);
int cwidth = oviewport.width - 2 * boxpad;
itembox->set_content_size (itembox, cwidth - item_border_width,
text_box_height);
selbox->set_content_size (selbox, cwidth - sel_border_width,
text_box_height);
int text_left_offset = self->icon_width + icon_text_space;
int item_text_top_offset = (text_box_height - (ascent + descent)) / 2 + ascent;
int sel_text_top_offset = (text_box_height - (selected_ascent
+ selected_descent)) / 2
+ selected_ascent;
grub_video_rect_t svpsave, sviewport;
sviewport.x = max_leftpad + text_left_offset;
int text_viewport_width = cwidth - sviewport.x;
sviewport.height = text_box_height;
grub_video_color_t item_color;
grub_video_color_t sel_color;
item_color = grub_video_map_rgba_color (self->item_color);
sel_color = grub_video_map_rgba_color (self->selected_item_color);
int item_box_top_offset = max_toppad - item_toppad;
int sel_box_top_offset = max_toppad - sel_toppad;
int item_viewport_width = text_viewport_width - item_rightpad;
int sel_viewport_width = text_viewport_width - sel_rightpad;
int tmp_icon_top_offset = (text_box_height - self->icon_height) / 2;
int item_icon_top_offset = item_toppad + tmp_icon_top_offset;
int sel_icon_top_offset = sel_toppad + tmp_icon_top_offset;
for (visible_index = 0, menu_index = self->first_shown_index;
visible_index < num_shown_items && menu_index < self->view->menu->size;
visible_index++, menu_index++)
{
int is_selected = (menu_index == self->view->selected);
struct grub_video_bitmap *icon;
grub_font_t font;
grub_video_color_t color;
int text_top_offset;
int top_pad;
int icon_top_offset;
int viewport_width;
if (is_selected)
{
selbox->draw (selbox, 0, item_top + sel_box_top_offset);
font = self->selected_item_font;
color = sel_color;
text_top_offset = sel_text_top_offset;
top_pad = sel_toppad;
icon_top_offset = sel_icon_top_offset;
viewport_width = sel_viewport_width;
}
else
{
itembox->draw (itembox, 0, item_top + item_box_top_offset);
font = self->item_font;
color = item_color;
text_top_offset = item_text_top_offset;
top_pad = item_toppad;
icon_top_offset = item_icon_top_offset;
viewport_width = item_viewport_width;
}
icon = get_item_icon (self, menu_index);
if (icon != 0)
grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
max_leftpad,
item_top + icon_top_offset,
0, 0, self->icon_width, self->icon_height);
const char *item_title =
grub_menu_get_entry (self->view->menu, menu_index)->title;
int off = self->view->menu_title_offset[menu_index];
const char *scrolled_title =
grub_utf8_offset_code (item_title, grub_strlen (item_title), off);
if (scrolled_title)
item_title = scrolled_title;
sviewport.y = item_top + top_pad;
sviewport.width = viewport_width;
grub_gui_set_viewport (&sviewport, &svpsave);
grub_font_draw_string (item_title,
font,
color,
0,
text_top_offset);
grub_gui_restore_viewport (&svpsave);
item_top += text_box_height + item_vspace;
}
grub_video_set_viewport (oviewport.x,
oviewport.y,
oviewport.width,
oviewport.height);
}
static void
list_paint (void *vself, const grub_video_rect_t *region)
{
list_impl_t self = vself;
grub_video_rect_t vpsave;
if (! self->visible)
return;
if (!grub_video_have_common_points (region, &self->bounds))
return;
check_boxes (self);
if (! self->menu_box || ! self->selected_item_box || ! self->item_box)
return;
grub_gui_set_viewport (&self->bounds, &vpsave);
{
grub_gfxmenu_box_t box = self->menu_box;
int box_left_pad = box->get_left_pad (box);
int box_top_pad = box->get_top_pad (box);
int box_right_pad = box->get_right_pad (box);
int box_bottom_pad = box->get_bottom_pad (box);
grub_video_rect_t vpsave2, content_rect;
int num_shown_items = get_num_shown_items (self);
int drawing_scrollbar = (self->draw_scrollbar
&& (num_shown_items < self->view->menu->size)
&& check_scrollbar (self));
int scrollbar_width = self->scrollbar_width;
content_rect.x = box_left_pad;
content_rect.y = box_top_pad;
content_rect.width = self->bounds.width - box_left_pad - box_right_pad;
content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad;
box->set_content_size (box, content_rect.width, content_rect.height);
box->draw (box, 0, 0);
switch (self->scrollbar_slice)
{
case SCROLLBAR_SLICE_WEST:
content_rect.x += self->scrollbar_right_pad;
content_rect.width -= self->scrollbar_right_pad;
break;
case SCROLLBAR_SLICE_CENTER:
if (drawing_scrollbar)
content_rect.width -= scrollbar_width + self->scrollbar_left_pad
+ self->scrollbar_right_pad;
break;
case SCROLLBAR_SLICE_EAST:
content_rect.width -= self->scrollbar_left_pad;
break;
}
grub_gui_set_viewport (&content_rect, &vpsave2);
draw_menu (self, num_shown_items);
grub_gui_restore_viewport (&vpsave2);
if (drawing_scrollbar)
{
content_rect.y += self->scrollbar_top_pad;
content_rect.height -= self->scrollbar_top_pad
+ self->scrollbar_bottom_pad;
content_rect.width = scrollbar_width;
switch (self->scrollbar_slice)
{
case SCROLLBAR_SLICE_WEST:
if (box_left_pad > scrollbar_width)
{
content_rect.x = box_left_pad - scrollbar_width;
content_rect.width = scrollbar_width;
}
else
{
content_rect.x = 0;
content_rect.width = box_left_pad;
}
break;
case SCROLLBAR_SLICE_CENTER:
content_rect.x = self->bounds.width - box_right_pad
- scrollbar_width - self->scrollbar_right_pad;
content_rect.width = scrollbar_width;
break;
case SCROLLBAR_SLICE_EAST:
content_rect.x = self->bounds.width - box_right_pad;
content_rect.width = box_right_pad;
break;
}
grub_gui_set_viewport (&content_rect, &vpsave2);
draw_scrollbar (self,
self->first_shown_index, num_shown_items,
0, self->view->menu->size,
scrollbar_width,
content_rect.height);
grub_gui_restore_viewport (&vpsave2);
}
}
grub_gui_restore_viewport (&vpsave);
}
static void
list_set_parent (void *vself, grub_gui_container_t parent)
{
list_impl_t self = vself;
self->parent = parent;
}
static grub_gui_container_t
list_get_parent (void *vself)
{
list_impl_t self = vself;
return self->parent;
}
static void
list_set_bounds (void *vself, const grub_video_rect_t *bounds)
{
list_impl_t self = vself;
self->bounds = *bounds;
}
static void
list_get_bounds (void *vself, grub_video_rect_t *bounds)
{
list_impl_t self = vself;
*bounds = self->bounds;
}
static void
list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
{
list_impl_t self = vself;
if (check_boxes (self))
{
int boxpad = self->item_padding;
int item_vspace = self->item_spacing;
int item_height = self->item_height;
int num_items = 3;
grub_gfxmenu_box_t box = self->menu_box;
int box_left_pad = box->get_left_pad (box);
int box_top_pad = box->get_top_pad (box);
int box_right_pad = box->get_right_pad (box);
int box_bottom_pad = box->get_bottom_pad (box);
unsigned width_s;
grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_top_pad = selbox->get_top_pad (selbox);
int sel_bottom_pad = selbox->get_bottom_pad (selbox);
int sel_left_pad = selbox->get_left_pad (selbox);
int sel_right_pad = selbox->get_right_pad (selbox);
grub_gfxmenu_box_t itembox = self->item_box;
int item_top_pad = itembox->get_top_pad (itembox);
int item_bottom_pad = itembox->get_bottom_pad (itembox);
int item_left_pad = itembox->get_left_pad (itembox);
int item_right_pad = itembox->get_right_pad (itembox);
int max_left_pad = grub_max (item_left_pad, sel_left_pad);
int max_right_pad = grub_max (item_right_pad, sel_right_pad);
int max_top_pad = grub_max (item_top_pad, sel_top_pad);
int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad);
*width = grub_font_get_string_width (self->item_font, "Typical OS");
width_s = grub_font_get_string_width (self->selected_item_font,
"Typical OS");
if (*width < width_s)
*width = width_s;
*width += 2 * boxpad + box_left_pad + box_right_pad
+ max_left_pad + max_right_pad
+ self->item_icon_space + self->icon_width;
switch (self->scrollbar_slice)
{
case SCROLLBAR_SLICE_WEST:
*width += self->scrollbar_right_pad;
break;
case SCROLLBAR_SLICE_CENTER:
*width += self->scrollbar_width + self->scrollbar_left_pad
+ self->scrollbar_right_pad;
break;
case SCROLLBAR_SLICE_EAST:
*width += self->scrollbar_left_pad;
break;
}
/* Set the menu box height to fit the items. */
*height = (item_height * num_items
+ item_vspace * (num_items - 1)
+ 2 * boxpad
+ box_top_pad + box_bottom_pad
+ max_top_pad + max_bottom_pad);
}
else
{
*width = 0;
*height = 0;
}
}
static grub_err_t
list_set_property (void *vself, const char *name, const char *value)
{
list_impl_t self = vself;
if (grub_strcmp (name, "item_font") == 0)
{
self->item_font = grub_font_get (value);
if (self->selected_item_font_inherit)
self->selected_item_font = self->item_font;
}
else if (grub_strcmp (name, "selected_item_font") == 0)
{
if (! value || grub_strcmp (value, "inherit") == 0)
{
self->selected_item_font = self->item_font;
self->selected_item_font_inherit = 1;
}
else
{
self->selected_item_font = grub_font_get (value);
self->selected_item_font_inherit = 0;
}
}
else if (grub_strcmp (name, "item_color") == 0)
{
grub_video_rgba_color_t color;
if (grub_video_parse_color (value, &color) == GRUB_ERR_NONE)
{
self->item_color = color;
if (self->selected_item_color_inherit)
self->selected_item_color = self->item_color;
}
}
else if (grub_strcmp (name, "selected_item_color") == 0)
{
if (! value || grub_strcmp (value, "inherit") == 0)
{
self->selected_item_color = self->item_color;
self->selected_item_color_inherit = 1;
}
else
{
grub_video_rgba_color_t color;
if (grub_video_parse_color (value, &color)
== GRUB_ERR_NONE)
{
self->selected_item_color = color;
self->selected_item_color_inherit = 0;
}
}
}
else if (grub_strcmp (name, "icon_width") == 0)
{
self->icon_width = grub_strtol (value, 0, 10);
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
self->icon_width,
self->icon_height);
}
else if (grub_strcmp (name, "icon_height") == 0)
{
self->icon_height = grub_strtol (value, 0, 10);
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
self->icon_width,
self->icon_height);
}
else if (grub_strcmp (name, "item_height") == 0)
{
self->item_height = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "item_padding") == 0)
{
self->item_padding = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "item_icon_space") == 0)
{
self->item_icon_space = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "item_spacing") == 0)
{
self->item_spacing = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "visible") == 0)
{
self->visible = grub_strcmp (value, "false") != 0;
}
else if (grub_strcmp (name, "menu_pixmap_style") == 0)
{
self->need_to_recreate_boxes = 1;
grub_free (self->menu_box_pattern);
self->menu_box_pattern = value ? grub_strdup (value) : 0;
}
else if (grub_strcmp (name, "item_pixmap_style") == 0)
{
self->need_to_recreate_boxes = 1;
grub_free (self->item_box_pattern);
self->item_box_pattern = value ? grub_strdup (value) : 0;
if (self->selected_item_box_pattern_inherit)
{
grub_free (self->selected_item_box_pattern);
self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
}
}
else if (grub_strcmp (name, "selected_item_pixmap_style") == 0)
{
if (!value || grub_strcmp (value, "inherit") == 0)
{
grub_free (self->selected_item_box_pattern);
char *tmp = self->item_box_pattern;
self->selected_item_box_pattern = tmp ? grub_strdup (tmp) : 0;
self->selected_item_box_pattern_inherit = 1;
}
else
{
self->need_to_recreate_boxes = 1;
grub_free (self->selected_item_box_pattern);
self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
self->selected_item_box_pattern_inherit = 0;
}
}
else if (grub_strcmp (name, "scrollbar_frame") == 0)
{
self->need_to_recreate_scrollbar = 1;
grub_free (self->scrollbar_frame_pattern);
self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0;
}
else if (grub_strcmp (name, "scrollbar_thumb") == 0)
{
self->need_to_recreate_scrollbar = 1;
grub_free (self->scrollbar_thumb_pattern);
self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0;
}
else if (grub_strcmp (name, "scrollbar_thumb_overlay") == 0)
{
self->scrollbar_thumb_overlay = grub_strcmp (value, "true") == 0;
}
else if (grub_strcmp (name, "scrollbar_width") == 0)
{
self->scrollbar_width = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "scrollbar_slice") == 0)
{
if (grub_strcmp (value, "west") == 0)
self->scrollbar_slice = SCROLLBAR_SLICE_WEST;
else if (grub_strcmp (value, "center") == 0)
self->scrollbar_slice = SCROLLBAR_SLICE_CENTER;
else if (grub_strcmp (value, "east") == 0)
self->scrollbar_slice = SCROLLBAR_SLICE_EAST;
}
else if (grub_strcmp (name, "scrollbar_left_pad") == 0)
{
self->scrollbar_left_pad = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "scrollbar_right_pad") == 0)
{
self->scrollbar_right_pad = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "scrollbar_top_pad") == 0)
{
self->scrollbar_top_pad = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "scrollbar_bottom_pad") == 0)
{
self->scrollbar_bottom_pad = grub_strtol (value, 0, 10);
}
else if (grub_strcmp (name, "scrollbar") == 0)
{
self->draw_scrollbar = grub_strcmp (value, "false") != 0;
}
else if (grub_strcmp (name, "theme_dir") == 0)
{
self->need_to_recreate_boxes = 1;
grub_free (self->theme_dir);
self->theme_dir = value ? grub_strdup (value) : 0;
}
else if (grub_strcmp (name, "id") == 0)
{
grub_free (self->id);
if (value)
self->id = grub_strdup (value);
else
self->id = 0;
}
return grub_errno;
}
/* Set necessary information that the gfxmenu view provides. */
static void
list_set_view_info (void *vself,
grub_gfxmenu_view_t view)
{
list_impl_t self = vself;
grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager,
view->theme_path);
self->view = view;
}
/* Refresh list variables */
static void
list_refresh_info (void *vself,
grub_gfxmenu_view_t view)
{
list_impl_t self = vself;
if (view->nested)
self->first_shown_index = 0;
}
static struct grub_gui_component_ops list_comp_ops =
{
.destroy = list_destroy,
.get_id = list_get_id,
.is_instance = list_is_instance,
.paint = list_paint,
.set_parent = list_set_parent,
.get_parent = list_get_parent,
.set_bounds = list_set_bounds,
.get_bounds = list_get_bounds,
.get_minimal_size = list_get_minimal_size,
.set_property = list_set_property
};
static struct grub_gui_list_ops list_ops =
{
.set_view_info = list_set_view_info,
.refresh_list = list_refresh_info
};
grub_gui_component_t
grub_gui_list_new (void)
{
list_impl_t self;
grub_font_t default_font;
grub_video_rgba_color_t default_fg_color;
self = grub_zalloc (sizeof (*self));
if (! self)
return 0;
self->list.ops = &list_ops;
self->list.component.ops = &list_comp_ops;
self->visible = 1;
default_font = grub_font_get ("Unknown Regular 16");
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
self->icon_width = 32;
self->icon_height = 32;
self->item_height = 42;
self->item_padding = 14;
self->item_icon_space = 4;
self->item_spacing = 16;
self->item_font = default_font;
self->selected_item_font_inherit = 1; /* Default to using the item_font. */
self->selected_item_font = default_font;
self->item_color = default_fg_color;
self->selected_item_color_inherit = 1; /* Default to using the item_color. */
self->selected_item_color = default_fg_color;
self->draw_scrollbar = 1;
self->need_to_recreate_scrollbar = 1;
self->scrollbar_frame = 0;
self->scrollbar_thumb = 0;
self->scrollbar_frame_pattern = 0;
self->scrollbar_thumb_pattern = 0;
self->scrollbar_thumb_overlay = 0;
self->scrollbar_width = 16;
self->scrollbar_slice = SCROLLBAR_SLICE_EAST;
self->scrollbar_left_pad = 2;
self->scrollbar_right_pad = 0;
self->scrollbar_top_pad = 0;
self->scrollbar_bottom_pad = 0;
self->first_shown_index = 0;
self->need_to_recreate_boxes = 0;
self->theme_dir = 0;
self->menu_box_pattern = 0;
self->item_box_pattern = 0;
self->selected_item_box_pattern_inherit = 1;/*Default to using the item_box.*/
self->selected_item_box_pattern = 0;
self->menu_box = grub_gfxmenu_create_box (0, 0);
self->item_box = grub_gfxmenu_create_box (0, 0);
self->selected_item_box = grub_gfxmenu_create_box (0, 0);
self->icon_manager = grub_gfxmenu_icon_manager_new ();
if (! self->icon_manager)
{
self->list.component.ops->destroy (self);
return 0;
}
grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
self->icon_width,
self->icon_height);
return (grub_gui_component_t) self;
}

View File

@ -163,6 +163,12 @@ theme_set_string (grub_gfxmenu_view_t view,
grub_video_parse_color (value, &view->message_color); grub_video_parse_color (value, &view->message_color);
else if (! grub_strcmp ("message-bg-color", name)) else if (! grub_strcmp ("message-bg-color", name))
grub_video_parse_color (value, &view->message_bg_color); grub_video_parse_color (value, &view->message_bg_color);
else if (! grub_strcmp("menu-tip-left", name))
grub_env_set("VTOY_TIP_LEFT", value);
else if (! grub_strcmp("menu-tip-top", name))
grub_env_set("VTOY_TIP_TOP", value);
else if (! grub_strcmp("menu-tip-color", name))
grub_env_set("VTOY_TIP_COLOR", value);
else if (! grub_strcmp ("desktop-image", name)) else if (! grub_strcmp ("desktop-image", name))
{ {
struct grub_video_bitmap *raw_bitmap; struct grub_video_bitmap *raw_bitmap;
@ -289,6 +295,8 @@ theme_set_string (grub_gfxmenu_view_t view,
if (! view->title_text) if (! view->title_text)
return grub_errno; return grub_errno;
} }
else if (! grub_strcmp ("ventoy_left_top_color", name))
return grub_errno;
else else
{ {
return grub_error (GRUB_ERR_BAD_ARGUMENT, return grub_error (GRUB_ERR_BAD_ARGUMENT,
@ -450,7 +458,8 @@ read_expression (struct parsebuf *p)
/* Read as a single word -- for numeric values or words without /* Read as a single word -- for numeric values or words without
whitespace. */ whitespace. */
start = p->pos; start = p->pos;
while (has_more (p) && ! is_whitespace (peek_char (p))) while (has_more (p) && ! is_whitespace (peek_char (p))
&& peek_char (p) != '}')
read_char (p); read_char (p);
end = p->pos; end = p->pos;
} }
@ -725,6 +734,11 @@ read_property (struct parsebuf *p)
"%s:%d:%d property value invalid; " "%s:%d:%d property value invalid; "
"enclose literal values in quotes (\")", "enclose literal values in quotes (\")",
p->filename, p->line_num, p->col_num); p->filename, p->line_num, p->col_num);
grub_printf("File: %s\nLine:%d Column:%d\n"
"property value invalid; enclose literal values in quotes (\")\n\n",
p->filename, p->line_num, p->col_num);
goto done; goto done;
} }
@ -740,6 +754,7 @@ extern int g_menu_update_mode;
grub_err_t grub_err_t
grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
{ {
int flag = 0;
grub_file_t file; grub_file_t file;
struct parsebuf p; struct parsebuf p;
@ -783,32 +798,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
} }
} }
{
const char *tip = grub_env_get("VTOY_MENU_TIP_ENABLE");
if (tip && tip[0] == '1')
{
char tmpmsg[512];
grub_memset(tmpmsg, 'w', 500);
tmpmsg[500] = 0;
g_menu_update_mode = 1;
p.len += grub_snprintf(p.buf + p.len, 4096,
"\n+ vbox{\n left = %s\n top = %s\n"
"+ label { id=\"VTOY_MENU_TIP_1\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
"+ label { id=\"VTOY_MENU_TIP_2\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
"}\n",
grub_env_get("VTOY_TIP_LEFT"),
grub_env_get("VTOY_TIP_TOP"),
tmpmsg,
grub_env_get("VTOY_TIP_COLOR"),
grub_env_get("VTOY_TIP_ALIGN"),
tmpmsg,
grub_env_get("VTOY_TIP_COLOR"),
grub_env_get("VTOY_TIP_ALIGN")
);
}
}
if (view->canvas) if (view->canvas)
view->canvas->component.ops->destroy (view->canvas); view->canvas->component.ops->destroy (view->canvas);
@ -820,6 +810,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
->ops->set_bounds ((grub_gui_component_t) view->canvas, ->ops->set_bounds ((grub_gui_component_t) view->canvas,
&view->screen); &view->screen);
parse:
while (has_more (&p)) while (has_more (&p))
{ {
/* Skip comments (lines beginning with #). */ /* Skip comments (lines beginning with #). */
@ -848,6 +839,40 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
goto fail; goto fail;
} }
if (flag == 0)
{
const char *tip = grub_env_get("VTOY_MENU_TIP_ENABLE");
if (tip && tip[0] == '1')
{
char tmpmsg[512];
grub_memset(tmpmsg, 'w', 500);
tmpmsg[500] = 0;
g_menu_update_mode = 1;
p.len += grub_snprintf(p.buf + p.len, 4096,
"\n+ vbox{\n left = %s\n top = %s\n"
"+ label { id=\"VTOY_MENU_TIP_1\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
"+ label { id=\"VTOY_MENU_TIP_2\" text = \"%s\" color = \"%s\" align = \"%s\"}\n"
"}\n",
grub_env_get("VTOY_TIP_LEFT"),
grub_env_get("VTOY_TIP_TOP"),
tmpmsg,
grub_env_get("VTOY_TIP_COLOR"),
grub_env_get("VTOY_TIP_ALIGN"),
tmpmsg,
grub_env_get("VTOY_TIP_COLOR"),
grub_env_get("VTOY_TIP_ALIGN")
);
flag = 1;
goto parse;
}
}
/* Set the new theme path. */ /* Set the new theme path. */
grub_free (view->theme_path); grub_free (view->theme_path);
view->theme_path = grub_strdup (theme_path); view->theme_path = grub_strdup (theme_path);

View File

@ -37,6 +37,7 @@
#include <grub/gui_string_util.h> #include <grub/gui_string_util.h>
#include <grub/icon_manager.h> #include <grub/icon_manager.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/charset.h>
static void static void
init_terminal (grub_gfxmenu_view_t view); init_terminal (grub_gfxmenu_view_t view);
@ -142,6 +143,8 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
grub_free (view->title_text); grub_free (view->title_text);
grub_free (view->progress_message_text); grub_free (view->progress_message_text);
grub_free (view->theme_path); grub_free (view->theme_path);
if (view->menu_title_offset)
grub_free (view->menu_title_offset);
if (view->canvas) if (view->canvas)
view->canvas->component.ops->destroy (view->canvas); view->canvas->component.ops->destroy (view->canvas);
grub_free (view); grub_free (view);
@ -428,6 +431,32 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data)
} }
void
grub_gfxmenu_scroll_chosen_entry (void *data, int diren)
{
grub_gfxmenu_view_t view = data;
const char *item_title;
int off;
int max;
if (!view->menu->size)
return;
item_title = grub_menu_get_entry (view->menu, view->selected)->title;
off = view->menu_title_offset[view->selected] + diren;
max = grub_utf8_get_num_code (item_title, grub_strlen(item_title));
if (diren == 1000000)
off = (max >= 20) ? (max - 20) : 0;
else if (off < 0)
off = 0;
else if (off > max)
off = max;
view->menu_title_offset[view->selected] = off;
grub_gfxmenu_redraw_menu (view);
}
static void static void
grub_gfxmenu_draw_terminal_box (void) grub_gfxmenu_draw_terminal_box (void)
{ {

View File

@ -471,7 +471,7 @@ grub_err_t
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_off_t offset, grub_size_t size, void *buf) grub_off_t offset, grub_size_t size, void *buf)
{ {
if (disk->read_hook == (grub_disk_read_hook_t)grub_disk_blocklist_read) if (disk->read_hook == (grub_disk_read_hook_t)(void *)grub_disk_blocklist_read)
{ {
return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size); return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size);
} }

View File

@ -49,6 +49,12 @@ static grub_efi_uintn_t finish_desc_size;
static grub_efi_uint32_t finish_desc_version; static grub_efi_uint32_t finish_desc_version;
int grub_efi_is_finished = 0; int grub_efi_is_finished = 0;
/* 160MB 160 * 1024 * 1024 / 4096 */
#define VTOY_CHAIN_MIN_PAGES (160 * 256)
static grub_efi_uint64_t g_total_pages;
static grub_efi_uint64_t g_org_required_pages;
static grub_efi_uint64_t g_new_required_pages;
/* /*
* We need to roll back EFI allocations on exit. Remember allocations that * We need to roll back EFI allocations on exit. Remember allocations that
* we'll free on exit. * we'll free on exit.
@ -614,6 +620,22 @@ grub_efi_mm_init (void)
else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE); required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
g_org_required_pages = required_pages;
if (((total_pages - required_pages) >> 2) < VTOY_CHAIN_MIN_PAGES)
{
if (total_pages > (VTOY_CHAIN_MIN_PAGES << 2))
{
g_new_required_pages = total_pages - (VTOY_CHAIN_MIN_PAGES << 2);
if (g_new_required_pages >= 8192)
{
required_pages = g_new_required_pages;
}
}
}
g_total_pages = total_pages;
g_new_required_pages = required_pages;
/* Sort the filtered descriptors, so that GRUB can allocate pages /* Sort the filtered descriptors, so that GRUB can allocate pages
from smaller regions. */ from smaller regions. */
sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
@ -670,3 +692,11 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
#endif #endif
void grub_efi_get_reserved_page_num(grub_uint64_t *total, grub_uint64_t *org_required, grub_uint64_t *new_required)
{
*total = g_total_pages;
*org_required = g_org_required_pages;
*new_required = g_new_required_pages;
}

View File

@ -0,0 +1,250 @@
/* env.c - Environment variables */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/env.h>
#include <grub/env_private.h>
#include <grub/misc.h>
#include <grub/mm.h>
/* The initial context. */
static struct grub_env_context initial_context;
/* The current context. */
struct grub_env_context *grub_current_context = &initial_context;
static grub_env_read_hook_t vtoy_menu_lang_read_hook;
/* Return the hash representation of the string S. */
static unsigned int
grub_env_hashval (const char *s)
{
unsigned int i = 0;
/* XXX: This can be done much more efficiently. */
while (*s)
i += 5 * *(s++);
return i % HASHSZ;
}
static struct grub_env_var *
grub_env_find (const char *name)
{
struct grub_env_var *var;
int idx = grub_env_hashval (name);
/* Look for the variable in the current context. */
for (var = grub_current_context->vars[idx]; var; var = var->next)
if (grub_strcmp (var->name, name) == 0)
return var;
return 0;
}
static void
grub_env_insert (struct grub_env_context *context,
struct grub_env_var *var)
{
int idx = grub_env_hashval (var->name);
/* Insert the variable into the hashtable. */
var->prevp = &context->vars[idx];
var->next = context->vars[idx];
if (var->next)
var->next->prevp = &(var->next);
context->vars[idx] = var;
}
static void
grub_env_remove (struct grub_env_var *var)
{
/* Remove the entry from the variable table. */
*var->prevp = var->next;
if (var->next)
var->next->prevp = var->prevp;
}
grub_err_t
grub_env_set (const char *name, const char *val)
{
struct grub_env_var *var;
/* If the variable does already exist, just update the variable. */
var = grub_env_find (name);
if (var)
{
char *old = var->value;
if (var->write_hook)
var->value = var->write_hook (var, val);
else
var->value = grub_strdup (val);
if (! var->value)
{
var->value = old;
return grub_errno;
}
grub_free (old);
return GRUB_ERR_NONE;
}
/* The variable does not exist, so create a new one. */
var = grub_zalloc (sizeof (*var));
if (! var)
return grub_errno;
var->name = grub_strdup (name);
if (! var->name)
goto fail;
var->value = grub_strdup (val);
if (! var->value)
goto fail;
grub_env_insert (grub_current_context, var);
return GRUB_ERR_NONE;
fail:
grub_free (var->name);
grub_free (var->value);
grub_free (var);
return grub_errno;
}
const char *
grub_env_get (const char *name)
{
struct grub_env_var *var;
if (name && vtoy_menu_lang_read_hook && grub_strncmp(name, "VTLANG_", 7) == 0)
return vtoy_menu_lang_read_hook(NULL, name);
var = grub_env_find (name);
if (! var)
return 0;
if (var->read_hook)
return var->read_hook (var, var->value);
return var->value;
}
void
grub_env_unset (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
return;
if (var->read_hook || var->write_hook)
{
grub_env_set (name, "");
return;
}
grub_env_remove (var);
grub_free (var->name);
grub_free (var->value);
grub_free (var);
}
struct grub_env_var *
grub_env_update_get_sorted (void)
{
struct grub_env_var *sorted_list = 0;
int i;
/* Add variables associated with this context into a sorted list. */
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *var;
for (var = grub_current_context->vars[i]; var; var = var->next)
{
struct grub_env_var *p, **q;
for (q = &sorted_list, p = *q; p; q = &((*q)->sorted_next), p = *q)
{
if (grub_strcmp (p->name, var->name) > 0)
break;
}
var->sorted_next = *q;
*q = var;
}
}
return sorted_list;
}
grub_err_t
grub_register_variable_hook (const char *name,
grub_env_read_hook_t read_hook,
grub_env_write_hook_t write_hook)
{
struct grub_env_var *var = grub_env_find (name);
if (! var)
{
if (grub_env_set (name, "") != GRUB_ERR_NONE)
return grub_errno;
var = grub_env_find (name);
/* XXX Insert an assertion? */
}
var->read_hook = read_hook;
var->write_hook = write_hook;
return GRUB_ERR_NONE;
}
grub_err_t
grub_register_vtoy_menu_lang_hook(grub_env_read_hook_t read_hook)
{
vtoy_menu_lang_read_hook = read_hook;
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_export (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
{
grub_err_t err;
err = grub_env_set (name, "");
if (err)
return err;
var = grub_env_find (name);
}
var->global = 1;
return GRUB_ERR_NONE;
}

View File

@ -106,20 +106,137 @@ int ventoy_check_file_exist(const char * fmt, ...)
} }
} }
typedef struct grub_vlnk
{
int srclen;
char src[512];
char dst[512];
struct grub_vlnk *next;
}grub_vlnk;
static grub_vlnk g_vtoy_vlnk;
static grub_vlnk *g_vlnk_list;
int grub_file_is_vlnk_suffix(const char *name, int len)
{
grub_uint32_t suffix;
if (len > 9)
{
suffix = *(grub_uint32_t *)(name + len - 4);
if (grub_strncmp(name + len - 9, ".vlnk.", 6) == 0)
{
/* .iso .wim .img .vhd .efi .dat */
if (suffix == 0x6F73692E || suffix == 0x6D69772E ||
suffix == 0x676D692E || suffix == 0x6468762E ||
suffix == 0x6966652E || suffix == 0x7461642E)
{
return 1;
}
}
else if (len > 10 && grub_strncmp(name + len - 10, ".vlnk.", 6) == 0)
{
/* vhdx vtoy */
if (suffix == 0x78646876 || suffix == 0x796F7476)
{
return 1;
}
}
}
return 0;
}
int grub_file_vtoy_vlnk(const char *src, const char *dst)
{
if (src)
{
g_vtoy_vlnk.srclen = (int)grub_strlen(src);
grub_strncpy(g_vtoy_vlnk.src, src, sizeof(g_vtoy_vlnk.src) - 1);
grub_strncpy(g_vtoy_vlnk.dst, dst, sizeof(g_vtoy_vlnk.dst) - 1);
}
else
{
g_vtoy_vlnk.srclen = 0;
g_vtoy_vlnk.src[0] = 0;
g_vtoy_vlnk.dst[0] = 0;
}
return 0;
}
int grub_file_add_vlnk(const char *src, const char *dst)
{
grub_vlnk *node = NULL;
if (src && dst)
{
node = grub_zalloc(sizeof(grub_vlnk));
if (node)
{
node->srclen = (int)grub_strlen(src);
grub_strncpy(node->src, src, sizeof(node->src) - 1);
grub_strncpy(node->dst, dst, sizeof(node->dst) - 1);
node->next = g_vlnk_list;
g_vlnk_list = node;
return 0;
}
}
return 1;
}
const char *grub_file_get_vlnk(const char *name, int *vlnk)
{
int len;
grub_vlnk *node = g_vlnk_list;
len = grub_strlen(name);
if (!grub_file_is_vlnk_suffix(name, len))
{
return name;
}
if (len == g_vtoy_vlnk.srclen && grub_strcmp(name, g_vtoy_vlnk.src) == 0)
{
if (vlnk)
*vlnk = 1;
return g_vtoy_vlnk.dst;
}
while (node)
{
if (node->srclen == len && grub_strcmp(name, node->src) == 0)
{
if (vlnk)
*vlnk = 1;
return node->dst;
}
node = node->next;
}
return name;
}
grub_file_t grub_file_t
grub_file_open (const char *name, enum grub_file_type type) grub_file_open (const char *name, enum grub_file_type type)
{ {
int vlnk = 0;
grub_device_t device = 0; grub_device_t device = 0;
grub_file_t file = 0, last_file = 0; grub_file_t file = 0, last_file = 0;
char *device_name; char *device_name;
const char *file_name; const char *file_name;
grub_file_filter_id_t filter; grub_file_filter_id_t filter;
/* <DESC> : mem:xxx:size:xxx format in chainloader */ /* <DESC> : mem:xxx:size:xxx format in chainloader grub_strlen(GRUB_MEMFILE_MEM) */
if (grub_strncmp(name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) { if (grub_strncmp(name, GRUB_MEMFILE_MEM, 4) == 0) {
return grub_memfile_open(name); return grub_memfile_open(name);
} }
if ((g_vlnk_list || g_vtoy_vlnk.srclen) && (type & GRUB_FILE_TYPE_NO_VLNK) == 0)
name = grub_file_get_vlnk(name, &vlnk);
device_name = grub_file_get_device_name (name); device_name = grub_file_get_device_name (name);
if (grub_errno) if (grub_errno)
goto fail; goto fail;
@ -141,6 +258,7 @@ grub_file_open (const char *name, enum grub_file_type type)
goto fail; goto fail;
file->device = device; file->device = device;
file->vlnk = vlnk;
/* In case of relative pathnames and non-Unix systems (like Windows) /* In case of relative pathnames and non-Unix systems (like Windows)
* name of host files may not start with `/'. Blocklists for host files * name of host files may not start with `/'. Blocklists for host files
@ -224,11 +342,13 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
if (len == 0) if (len == 0)
return 0; return 0;
if (file->name) {
if (grub_strncmp(file->name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) { if (grub_strncmp(file->name, GRUB_MEMFILE_MEM, grub_strlen(GRUB_MEMFILE_MEM)) == 0) {
grub_memcpy(buf, (grub_uint8_t *)(file->data) + file->offset, len); grub_memcpy(buf, (grub_uint8_t *)(file->data) + file->offset, len);
file->offset += len; file->offset += len;
return len; return len;
} }
}
read_hook = file->read_hook; read_hook = file->read_hook;
read_hook_data = file->read_hook_data; read_hook_data = file->read_hook_data;

View File

@ -42,6 +42,44 @@ probe_dummy_iter (const char *filename __attribute__ ((unused)),
return 1; return 1;
} }
grub_fs_t grub_fs_list_probe(grub_device_t device, const char **list)
{
int i;
grub_fs_t p;
if (!device->disk)
return 0;
for (p = grub_fs_list; p; p = p->next)
{
for (i = 0; list[i]; i++)
{
if (grub_strcmp(p->name, list[i]) == 0)
break;
}
if (list[i] == NULL)
continue;
grub_dprintf("fs", "Detecting %s...\n", p->name);
(p->fs_dir) (device, "/", probe_dummy_iter, NULL);
if (grub_errno == GRUB_ERR_NONE)
return p;
grub_error_push ();
grub_dprintf ("fs", "%s detection failed.\n", p->name);
grub_error_pop ();
if (grub_errno != GRUB_ERR_BAD_FS && grub_errno != GRUB_ERR_OUT_OF_RANGE) {
return 0;
}
grub_errno = GRUB_ERR_NONE;
}
return 0;
}
grub_fs_t grub_fs_t
grub_fs_probe (grub_device_t device) grub_fs_probe (grub_device_t device)
{ {

View File

@ -362,7 +362,8 @@ static grub_err_t
cmd_append (const char *line, struct syslinux_menu *menu) cmd_append (const char *line, struct syslinux_menu *menu)
{ {
if (!menu->entries) if (!menu->entries)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); return GRUB_ERR_NONE;
//return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
menu->entries->append = grub_strdup (line); menu->entries->append = grub_strdup (line);
if (!menu->entries->append) if (!menu->entries->append)

View File

@ -229,10 +229,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (! file) if (! file)
goto fail; goto fail;
/* Get the root device's device path. */ dev = file->device;
dev = grub_device_open (0);
if (! dev)
goto fail;
if (dev->disk) if (dev->disk)
dev_handle = grub_efidisk_get_device_handle (dev->disk); dev_handle = grub_efidisk_get_device_handle (dev->disk);
@ -257,15 +254,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (dev_handle) if (dev_handle)
dp = grub_efi_get_device_path (dev_handle); dp = grub_efi_get_device_path (dev_handle);
if (! dp) if (dp != NULL)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
goto fail;
}
file_path = make_file_path (dp, filename); file_path = make_file_path (dp, filename);
if (! file_path) if (! file_path)
goto fail; goto fail;
}
//grub_printf ("file path: "); //grub_printf ("file path: ");
//grub_efi_print_device_path (file_path); //grub_efi_print_device_path (file_path);
@ -390,16 +384,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
} }
grub_file_close (file); grub_file_close (file);
grub_device_close (dev);
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
return 0; return 0;
fail: fail:
if (dev)
grub_device_close (dev);
if (file) if (file)
grub_file_close (file); grub_file_close (file);

View File

@ -88,6 +88,8 @@ static int ventoy_linux_argc = 0;
static char **ventoy_linux_args = NULL; static char **ventoy_linux_args = NULL;
static int ventoy_extra_initrd_num = 0; static int ventoy_extra_initrd_num = 0;
static char *ventoy_extra_initrd_list[256]; static char *ventoy_extra_initrd_list[256];
static grub_command_func_t ventoy_linux16_func = NULL;
static grub_command_func_t ventoy_initrd16_func = NULL;
static grub_err_t static grub_err_t
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]); grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]);
@ -667,54 +669,6 @@ static int ventoy_bootopt_hook(int argc, char *argv[])
return 0; return 0;
} }
static grub_err_t
grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int i;
const char *vtdebug;
for (i = 0; i < argc; i++)
{
ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
ventoy_linux_argc++;
}
vtdebug = grub_env_get("vtdebug_flag");
if (vtdebug && vtdebug[0])
{
ventoy_debug = 1;
}
if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
return 0;
}
static grub_err_t
grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int i;
(void)argc;
(void)argv;
for (i = 0; i < LINUX_MAX_ARGC; i++)
{
if (ventoy_linux_args[i])
{
grub_free(ventoy_linux_args[i]);
}
}
ventoy_debug = 0;
ventoy_linux_argc = 0;
ventoy_initrd_called = 0;
grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
return 0;
}
static grub_err_t static grub_err_t
grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
@ -1576,6 +1530,92 @@ ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list);
} }
static grub_err_t
grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int i;
const char *vtdebug;
grub_command_t regcmd;
for (i = 0; i < argc; i++)
{
ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]);
ventoy_linux_argc++;
}
vtdebug = grub_env_get("vtdebug_flag");
if (vtdebug && vtdebug[0])
{
ventoy_debug = 1;
}
if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc);
ventoy_linux16_func = ventoy_initrd16_func = NULL;
regcmd = grub_command_find("linux16");
if (regcmd)
{
ventoy_linux16_func = regcmd->func;
regcmd->func = grub_cmd_linux;
}
regcmd = grub_command_find("initrd16");
if (regcmd)
{
ventoy_initrd16_func = regcmd->func;
regcmd->func = ventoy_cmd_initrd;
}
return 0;
}
static grub_err_t
grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int i;
grub_command_t regcmd;
(void)argc;
(void)argv;
for (i = 0; i < LINUX_MAX_ARGC; i++)
{
if (ventoy_linux_args[i])
{
grub_free(ventoy_linux_args[i]);
}
}
ventoy_debug = 0;
ventoy_linux_argc = 0;
ventoy_initrd_called = 0;
grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC);
if (ventoy_linux16_func)
{
regcmd = grub_command_find("linux16");
if (regcmd)
{
regcmd->func = ventoy_linux16_func;
}
ventoy_linux16_func = NULL;
}
if (ventoy_initrd16_func)
{
regcmd = grub_command_find("initrd16");
if (regcmd)
{
regcmd->func = ventoy_initrd16_func;
}
ventoy_initrd16_func = NULL;
}
return 0;
}
static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi; static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi;
static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset;

File diff suppressed because it is too large Load Diff

View File

@ -48,10 +48,35 @@ int g_ventoy_suppress_esc = 0;
int g_ventoy_suppress_esc_default = 1; int g_ventoy_suppress_esc_default = 1;
int g_ventoy_menu_esc = 0; int g_ventoy_menu_esc = 0;
int g_ventoy_fn_mutex = 0; int g_ventoy_fn_mutex = 0;
int g_ventoy_secondary_menu_on = 0;
int g_ventoy_terminal_output = 0; int g_ventoy_terminal_output = 0;
char g_ventoy_hotkey_tip[256];
static int g_vt_key_num = 0;
static int g_vt_key_code[128];
static int ventoy_menu_pop_key(void)
{
if (g_vt_key_num > 0 && g_vt_key_num < (int)(sizeof(g_vt_key_code) / sizeof(g_vt_key_code[0])))
{
g_vt_key_num--;
return g_vt_key_code[g_vt_key_num];
}
return -1;
}
int ventoy_menu_push_key(int code)
{
if (g_vt_key_num >= 0 && g_vt_key_num < (int)(sizeof(g_vt_key_code) / sizeof(g_vt_key_code[0])))
{
g_vt_key_code[g_vt_key_num++] = code;
return 0;
}
return -1;
}
#define VTOY_COMM_HOTKEY(cmdkey) \ #define VTOY_COMM_HOTKEY(cmdkey) \
if (0 == g_ventoy_fn_mutex) { \ if (0 == g_ventoy_fn_mutex && 0 == g_ventoy_secondary_menu_on) { \
cmdstr = grub_env_get(cmdkey); \ cmdstr = grub_env_get(cmdkey); \
if (cmdstr) \ if (cmdstr) \
{ \ { \
@ -461,6 +486,15 @@ menu_set_chosen_entry (grub_menu_t menu, int entry)
cur->set_chosen_entry (entry, cur->data); cur->set_chosen_entry (entry, cur->data);
} }
static void
menu_scroll_chosen_entry (int diren)
{
struct grub_menu_viewer *cur;
for (cur = viewers; cur; cur = cur->next)
if (cur->scroll_chosen_entry)
cur->scroll_chosen_entry (cur->data, diren);
}
static void static void
menu_print_timeout (int timeout) menu_print_timeout (int timeout)
{ {
@ -671,9 +705,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
if (g_ventoy_suppress_esc) if (g_ventoy_suppress_esc)
default_entry = g_ventoy_suppress_esc_default; default_entry = g_ventoy_suppress_esc_default;
else if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) {
default_entry = g_ventoy_last_entry;
}
/* If DEFAULT_ENTRY is not within the menu entries, fall back to /* If DEFAULT_ENTRY is not within the menu entries, fall back to
the first entry. */ the first entry. */
else if (default_entry < 0 || default_entry >= menu->size) else if (default_entry < 0 || default_entry >= menu->size)
@ -788,7 +820,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
return default_entry; return default_entry;
} }
if (g_vt_key_num > 0) {
c = ventoy_menu_pop_key();
} else {
c = grub_getkey_noblock (); c = grub_getkey_noblock ();
}
/* Negative values are returned on error. */ /* Negative values are returned on error. */
if ((c != GRUB_TERM_NO_KEY) && (c > 0)) if ((c != GRUB_TERM_NO_KEY) && (c > 0))
@ -848,6 +884,19 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
menu_set_chosen_entry (menu, current_entry); menu_set_chosen_entry (menu, current_entry);
break; break;
case GRUB_TERM_KEY_RIGHT:
menu_scroll_chosen_entry (1);
break;
case GRUB_TERM_KEY_LEFT:
menu_scroll_chosen_entry (-1);
break;
case GRUB_TERM_CTRL | GRUB_TERM_KEY_RIGHT:
menu_scroll_chosen_entry (1000000);
break;
case GRUB_TERM_CTRL | GRUB_TERM_KEY_LEFT:
menu_scroll_chosen_entry (-1000000);
break;
case '\n': case '\n':
case '\r': case '\r':
// case GRUB_TERM_KEY_RIGHT: // case GRUB_TERM_KEY_RIGHT:
@ -902,48 +951,18 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
menu_fini (); menu_fini ();
if (g_ventoy_terminal_output == 0) if (g_ventoy_terminal_output == 0)
{ {
grub_script_execute_sourcecode("terminal_output console"); grub_script_execute_sourcecode("vt_push_menu_lang en_US\nterminal_output console");
g_ventoy_terminal_output = 1; g_ventoy_terminal_output = 1;
} }
else else
{ {
grub_script_execute_sourcecode("terminal_output gfxterm"); grub_script_execute_sourcecode("terminal_output gfxterm\nvt_pop_menu_lang");
g_ventoy_terminal_output = 0; g_ventoy_terminal_output = 0;
} }
goto refresh; goto refresh;
case GRUB_TERM_KEY_F1: case GRUB_TERM_KEY_F1:
case '1': case '1':
menu_fini (); if (0 == g_ventoy_secondary_menu_on)
g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'i'):
menu_fini ();
g_ventoy_iso_raw = 1 - g_ventoy_iso_raw;
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'r'):
menu_fini ();
g_ventoy_grub2_mode = 1 - g_ventoy_grub2_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'w'):
menu_fini ();
g_ventoy_wimboot_mode = 1 - g_ventoy_wimboot_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'u'):
menu_fini ();
g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv;
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'h'):
case 'h':
{ {
cmdstr = grub_env_get("VTOY_HELP_CMD"); cmdstr = grub_env_get("VTOY_HELP_CMD");
if (cmdstr) if (cmdstr)
@ -954,10 +973,72 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
menu_fini (); menu_fini ();
goto refresh; goto refresh;
} }
}
break;
case (GRUB_TERM_CTRL | 'd'):
case 'd':
if (0 == g_ventoy_secondary_menu_on)
{
menu_fini ();
g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
}
break;
case (GRUB_TERM_CTRL | 'i'):
case 'i':
if (0 == g_ventoy_secondary_menu_on)
{
menu_fini ();
g_ventoy_iso_raw = 1 - g_ventoy_iso_raw;
g_ventoy_menu_refresh = 1;
goto refresh;
}
break;
case (GRUB_TERM_CTRL | 'r'):
case 'r':
if (0 == g_ventoy_secondary_menu_on)
{
menu_fini ();
g_ventoy_grub2_mode = 1 - g_ventoy_grub2_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
}
break;
case (GRUB_TERM_CTRL | 'w'):
case 'w':
if (0 == g_ventoy_secondary_menu_on)
{
menu_fini ();
g_ventoy_wimboot_mode = 1 - g_ventoy_wimboot_mode;
g_ventoy_menu_refresh = 1;
goto refresh;
}
break;
case (GRUB_TERM_CTRL | 'u'):
case 'u':
if (0 == g_ventoy_secondary_menu_on)
{
menu_fini ();
g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv;
g_ventoy_menu_refresh = 1;
goto refresh;
}
break;
case (GRUB_TERM_CTRL | 'l'):
case (GRUB_TERM_CTRL | 'L'):
case (GRUB_TERM_SHIFT | 'l'):
case (GRUB_TERM_SHIFT | 'L'):
case 'l':
case 'L':
{
VTOY_COMM_HOTKEY("VTOY_LANG_CMD");
break; break;
} }
case (GRUB_TERM_CTRL | 'm'): case (GRUB_TERM_CTRL | 'm'):
case 'm': case 'm':
{
if (0 == g_ventoy_secondary_menu_on)
{ {
if (g_ventoy_cur_img_path) if (g_ventoy_cur_img_path)
{ {
@ -974,6 +1055,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
{ {
grub_env_set("VTOY_CHKSUM_FILE_PATH", "X"); grub_env_set("VTOY_CHKSUM_FILE_PATH", "X");
} }
}
break; break;
} }
default: default:
@ -1051,6 +1133,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
while (1) while (1)
{ {
int ndown;
int boot_entry; int boot_entry;
grub_menu_entry_t e; grub_menu_entry_t e;
int auto_boot; int auto_boot;
@ -1093,6 +1176,16 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_RET", 12) == 0) if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_RET", 12) == 0)
break; break;
else if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_SET", 12) == 0) {
ndown = (int)grub_strtol(e->args[1] + 12, NULL, 10);
while (ndown > 0)
{
ventoy_menu_push_key(GRUB_TERM_KEY_DOWN);
ndown--;
}
ventoy_menu_push_key('\n');
break;
}
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;

View File

@ -31,6 +31,8 @@
static grub_uint8_t grub_color_menu_normal; static grub_uint8_t grub_color_menu_normal;
static grub_uint8_t grub_color_menu_highlight; static grub_uint8_t grub_color_menu_highlight;
extern char g_ventoy_hotkey_tip[256];
struct menu_viewer_data struct menu_viewer_data
{ {
int first, offset; int first, offset;
@ -42,6 +44,7 @@ struct menu_viewer_data
TIMEOUT_TERSE_NO_MARGIN TIMEOUT_TERSE_NO_MARGIN
} timeout_msg; } timeout_msg;
grub_menu_t menu; grub_menu_t menu;
int *menu_title_offset;
struct grub_term_output *term; struct grub_term_output *term;
}; };
@ -203,7 +206,7 @@ command-line or ESC to discard edits and return to the GRUB menu."),
ret += grub_print_message_indented_real(szLine, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ret += grub_print_message_indented_real(szLine, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
ret += grub_print_message_indented_real(grub_env_get("VTOY_HOTKEY_TIP"), ret += grub_print_message_indented_real(g_ventoy_hotkey_tip,
3, 6, term, dry_run); 3, 6, term, dry_run);
} }
} }
@ -524,6 +527,37 @@ menu_text_set_chosen_entry (int entry, void *dataptr)
grub_term_refresh (data->term); grub_term_refresh (data->term);
} }
static void
menu_text_scroll_chosen_entry (void *dataptr, int diren)
{
struct menu_viewer_data *data = dataptr;
const char *orig_title, *scrolled_title;
int off;
int selected;
grub_menu_entry_t entry;
if (!data->menu->size)
return;
selected = data->first + data->offset;
entry = grub_menu_get_entry (data->menu, selected);
orig_title = entry->title;
off = data->menu_title_offset[selected] + diren;
if (off < 0
|| off > grub_utf8_get_num_code (orig_title, grub_strlen(orig_title)))
return;
scrolled_title =
grub_utf8_offset_code (orig_title, grub_strlen (orig_title), off);
if (scrolled_title)
entry->title = scrolled_title;
print_entry (data->geo.first_entry_y + data->offset, 1, entry, data);
entry->title = orig_title;
data->menu_title_offset[selected] = off;
grub_term_refresh (data->term);
}
static void static void
menu_text_fini (void *dataptr) menu_text_fini (void *dataptr)
{ {
@ -531,6 +565,8 @@ menu_text_fini (void *dataptr)
grub_term_setcursor (data->term, 1); grub_term_setcursor (data->term, 1);
grub_term_cls (data->term); grub_term_cls (data->term);
if (data->menu_title_offset)
grub_free (data->menu_title_offset);
grub_free (data); grub_free (data);
} }
@ -585,9 +621,14 @@ grub_menu_try_text (struct grub_term_output *term,
return grub_errno; return grub_errno;
} }
if (menu->size)
data->menu_title_offset = grub_zalloc (sizeof (*data->menu_title_offset) * menu->size);
data->term = term; data->term = term;
instance->data = data; instance->data = data;
instance->set_chosen_entry = menu_text_set_chosen_entry; instance->set_chosen_entry = menu_text_set_chosen_entry;
if (data->menu_title_offset)
instance->scroll_chosen_entry = menu_text_scroll_chosen_entry;
instance->print_timeout = menu_text_print_timeout; instance->print_timeout = menu_text_print_timeout;
instance->clear_timeout = menu_text_clear_timeout; instance->clear_timeout = menu_text_clear_timeout;
instance->fini = menu_text_fini; instance->fini = menu_text_fini;

View File

@ -0,0 +1,260 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 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/term.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/err.h>
#include <grub/env.h>
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_EFI_SIMPLE_POINTER_GUID \
{ 0x31878c87, 0x0b75, 0x11d5, \
{ 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
typedef struct
{
grub_efi_int32_t x;
grub_efi_int32_t y;
grub_efi_int32_t z;
grub_efi_boolean_t left;
grub_efi_boolean_t right;
} grub_efi_mouse_state;
grub_efi_mouse_state no_move = {0, 0, 0, 0, 0};
typedef struct
{
grub_efi_uint64_t x;
grub_efi_uint64_t y;
grub_efi_uint64_t z;
grub_efi_boolean_t left;
grub_efi_boolean_t right;
} grub_efi_mouse_mode;
struct grub_efi_simple_pointer_protocol
{
grub_efi_status_t (*reset) (struct grub_efi_simple_pointer_protocol *this,
grub_efi_boolean_t extended_verification);
grub_efi_status_t (*get_state) (struct grub_efi_simple_pointer_protocol *this,
grub_efi_mouse_state *state);
grub_efi_event_t *wait_for_input;
grub_efi_mouse_mode *mode;
};
typedef struct grub_efi_simple_pointer_protocol grub_efi_simple_pointer_protocol_t;
typedef struct
{
grub_efi_uintn_t count;
grub_efi_simple_pointer_protocol_t **mouse;
} grub_efi_mouse_prot_t;
static grub_int32_t
mouse_div (grub_int32_t a, grub_uint64_t b)
{
grub_int32_t s = 1, q, ret;
grub_uint64_t n = a;
if (!b)
return 0;
if (a < 0)
{
s = -1;
n = -a;
}
q = grub_divmod64 (n, b, NULL);
ret = s * (q > 0 ? q : -q);
return ret;
}
static grub_efi_mouse_prot_t *
grub_efi_mouse_prot_init (void)
{
grub_efi_status_t status;
grub_efi_guid_t mouse_guid = GRUB_EFI_SIMPLE_POINTER_GUID;
grub_efi_mouse_prot_t *mouse_input = NULL;
grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
grub_efi_handle_t *buf;
grub_efi_uintn_t count;
grub_efi_uintn_t i;
status = efi_call_5 (b->locate_handle_buffer, GRUB_EFI_BY_PROTOCOL,
&mouse_guid, NULL, &count, &buf);
if (status != GRUB_EFI_SUCCESS)
{
#ifdef MOUSE_DEBUG
grub_printf ("ERROR: SimplePointerProtocol not found.\n");
#endif
return NULL;
}
mouse_input = grub_malloc (sizeof (grub_efi_mouse_prot_t));
if (!mouse_input)
goto end;
mouse_input->mouse = grub_malloc (count
* sizeof (grub_efi_simple_pointer_protocol_t *));
if (!mouse_input->mouse)
{
grub_free (mouse_input);
mouse_input = NULL;
goto end;
}
mouse_input->count = count;
for (i = 0; i < count; i++)
{
efi_call_3 (b->handle_protocol,
buf[i], &mouse_guid, (void **)&mouse_input->mouse[i]);
#ifdef MOUSE_DEBUG
grub_printf ("%d %p ", (int)i, mouse_input->mouse[i]);
#endif
efi_call_2 (mouse_input->mouse[i]->reset, mouse_input->mouse[i], 1);
#ifdef MOUSE_DEBUG
grub_printf
("[%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"]\n",
mouse_input->mouse[i]->mode->x,
mouse_input->mouse[i]->mode->y, mouse_input->mouse[i]->mode->z);
#endif
}
end:
efi_call_1(b->free_pool, buf);
return mouse_input;
}
static grub_err_t
grub_efi_mouse_input_init (struct grub_term_input *term)
{
grub_efi_mouse_prot_t *mouse_input = NULL;
if (term->data)
return 0;
mouse_input = grub_efi_mouse_prot_init ();
if (!mouse_input)
return GRUB_ERR_BAD_OS;
term->data = (void *)mouse_input;
return 0;
}
static int
grub_mouse_getkey (struct grub_term_input *term)
{
grub_efi_mouse_state cur;
grub_efi_mouse_prot_t *mouse = term->data;
//int x;
int y;
int delta = 0;
const char *env;
grub_efi_uintn_t i;
if (!mouse)
return GRUB_TERM_NO_KEY;
env = grub_env_get("mouse_delta");
if (env)
delta = (int)grub_strtol(env, NULL, 10);
for (i = 0; i < mouse->count; i++)
{
efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur);
if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0)
{
y = mouse_div (cur.y, mouse->mouse[i]->mode->y);
if (cur.left)
return 0x0d;
if (cur.right)
return GRUB_TERM_ESC;
if (y > delta)
return GRUB_TERM_KEY_DOWN;
if (y < -delta)
return GRUB_TERM_KEY_UP;
}
}
return GRUB_TERM_NO_KEY;
}
#ifdef MOUSE_DEBUG
static grub_err_t
grub_cmd_mouse_test (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_efi_mouse_state cur;
int x = 0, y = 0, z = 0;
grub_efi_uintn_t i;
grub_efi_mouse_prot_t *mouse = NULL;
mouse = grub_efi_mouse_prot_init ();
if (!mouse)
return grub_error (GRUB_ERR_BAD_OS, "mouse not found.\n");
grub_printf ("Press [1] to exit.\n");
while (1)
{
if (grub_getkey_noblock () == '1')
break;
for (i = 0; i < mouse->count; i++)
{
efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur);
if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0)
{
x = mouse_div (cur.x, mouse->mouse[i]->mode->x);
y = mouse_div (cur.y, mouse->mouse[i]->mode->y);
z = mouse_div (cur.z, mouse->mouse[i]->mode->z);
grub_printf ("[ID=%d] X=%d Y=%d Z=%d L=%d R=%d\n",
(int)i, x, y, z, cur.left, cur.right);
}
}
grub_refresh ();
}
grub_free (mouse->mouse);
grub_free (mouse);
return GRUB_ERR_NONE;
}
static grub_command_t cmd;
#endif
static struct grub_term_input grub_mouse_term_input =
{
.name = "mouse",
.getkey = grub_mouse_getkey,
.init = grub_efi_mouse_input_init,
};
GRUB_MOD_INIT(mouse)
{
grub_term_register_input ("mouse", &grub_mouse_term_input);
#ifdef MOUSE_DEBUG
cmd = grub_register_command ("mouse_test", grub_cmd_mouse_test, 0,
N_("UEFI mouse test."));
#endif
}
GRUB_MOD_FINI(mouse)
{
grub_term_unregister_input (&grub_mouse_term_input);
#ifdef MOUSE_DEBUG
grub_unregister_command (cmd);
#endif
}

View File

@ -35,6 +35,11 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/kernel.h> #include <grub/kernel.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/memory.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#include <grub/efi/memory.h>
#endif
#include <grub/ventoy.h> #include <grub/ventoy.h>
#include "ventoy_def.h" #include "ventoy_def.h"
@ -71,7 +76,130 @@ void ventoy_str_toupper(char *str)
} }
} }
char *ventoy_str_last(char *str, char ch)
{
char *pos = NULL;
char *last = NULL;
if (!str)
{
return NULL;
}
for (pos = str; *pos; pos++)
{
if (*pos == ch)
{
last = pos;
}
}
return last;
}
int ventoy_str_all_digit(const char *str)
{
if (NULL == str || 0 == *str)
{
return 0;
}
while (*str)
{
if (*str < '0' || *str > '9')
{
return 0;
}
}
return 1;
}
int ventoy_str_all_alnum(const char *str)
{
if (NULL == str || 0 == *str)
{
return 0;
}
while (*str)
{
if (!grub_isalnum(*str))
{
return 0;
}
}
return 1;
}
int ventoy_str_len_alnum(const char *str, int len)
{
int i;
int slen;
if (NULL == str || 0 == *str)
{
return 0;
}
slen = grub_strlen(str);
if (slen <= len)
{
return 0;
}
for (i = 0; i < len; i++)
{
if (!grub_isalnum(str[i]))
{
return 0;
}
}
if (str[len] == 0 || grub_isspace(str[len]))
{
return 1;
}
return 0;
}
char * ventoy_str_basename(char *path)
{
char *pos = NULL;
pos = grub_strrchr(path, '/');
if (pos)
{
pos++;
}
else
{
pos = path;
}
return pos;
}
int ventoy_str_chrcnt(const char *str, char c)
{
int n = 0;
if (str)
{
while (*str)
{
if (*str == c)
{
n++;
}
str++;
}
}
return n;
}
int ventoy_strcmp(const char *pattern, const char *str) int ventoy_strcmp(const char *pattern, const char *str)
{ {
@ -104,6 +232,14 @@ int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n)
return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str;
} }
grub_err_t ventoy_env_int_set(const char *name, int value)
{
char buf[16];
grub_snprintf(buf, sizeof(buf), "%d", value);
return grub_env_set(name, buf);
}
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid) void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid)
{ {
int i; int i;
@ -131,6 +267,37 @@ int ventoy_is_efi_os(void)
return g_efi_os; return g_efi_os;
} }
void * ventoy_alloc_chain(grub_size_t size)
{
void *p = NULL;
p = grub_malloc(size);
#ifdef GRUB_MACHINE_EFI
if (!p)
{
p = grub_efi_allocate_any_pages(GRUB_EFI_BYTES_TO_PAGES(size));
}
#endif
return p;
}
void ventoy_memfile_env_set(const char *prefix, const void *buf, unsigned long long len)
{
char name[128];
char val[64];
grub_snprintf(name, sizeof(name), "%s_addr", prefix);
grub_snprintf(val, sizeof(val), "0x%llx", (ulonglong)(ulong)buf);
grub_env_set(name, val);
grub_snprintf(name, sizeof(name), "%s_size", prefix);
grub_snprintf(val, sizeof(val), "%llu", len);
grub_env_set(name, val);
return;
}
static int ventoy_arch_mode_init(void) static int ventoy_arch_mode_init(void)
{ {
#ifdef GRUB_MACHINE_EFI #ifdef GRUB_MACHINE_EFI
@ -162,8 +329,170 @@ static int ventoy_arch_mode_init(void)
return 0; return 0;
} }
#ifdef GRUB_MACHINE_EFI
static void ventoy_get_uefi_version(char *str, grub_size_t len)
{
grub_efi_uint8_t uefi_minor_1, uefi_minor_2;
uefi_minor_1 = (grub_efi_system_table->hdr.revision & 0xffff) / 10;
uefi_minor_2 = (grub_efi_system_table->hdr.revision & 0xffff) % 10;
grub_snprintf(str, len, "%d.%d", (grub_efi_system_table->hdr.revision >> 16), uefi_minor_1);
if (uefi_minor_2)
grub_snprintf(str, len, "%s.%d", str, uefi_minor_2);
}
#endif
static int ventoy_calc_totalmem(grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, void *data)
{
grub_uint64_t *total_mem = (grub_uint64_t *)data;
(void)addr;
(void)type;
*total_mem += size;
return 0;
}
static int ventoy_hwinfo_init(void)
{
char str[256];
grub_uint64_t total_mem = 0;
grub_machine_mmap_iterate(ventoy_calc_totalmem, &total_mem);
grub_snprintf(str, sizeof(str), "%ld", (long)(total_mem / VTOY_SIZE_1MB));
ventoy_env_export("grub_total_ram", str);
#ifdef GRUB_MACHINE_EFI
ventoy_get_uefi_version(str, sizeof(str));
ventoy_env_export("grub_uefi_version", str);
#else
ventoy_env_export("grub_uefi_version", "NA");
#endif
return 0;
}
static global_var_cfg g_global_vars[] =
{
{ "gfxmode", "1024x768", NULL },
{ ventoy_left_key, "5%", NULL },
{ ventoy_top_key, "95%", NULL },
{ ventoy_color_key, "#0000ff", NULL },
{ NULL, NULL, NULL }
};
static const char * ventoy_global_var_read_hook(struct grub_env_var *var, const char *val)
{
int i;
for (i = 0; g_global_vars[i].name; i++)
{
if (grub_strcmp(g_global_vars[i].name, var->name) == 0)
{
return g_global_vars[i].value;
}
}
return val;
}
static char * ventoy_global_var_write_hook(struct grub_env_var *var, const char *val)
{
int i;
for (i = 0; g_global_vars[i].name; i++)
{
if (grub_strcmp(g_global_vars[i].name, var->name) == 0)
{
grub_check_free(g_global_vars[i].value);
g_global_vars[i].value = grub_strdup(val);
break;
}
}
return grub_strdup(val);
}
int ventoy_global_var_init(void)
{
int i;
for (i = 0; g_global_vars[i].name; i++)
{
g_global_vars[i].value = grub_strdup(g_global_vars[i].defval);
ventoy_env_export(g_global_vars[i].name, g_global_vars[i].defval);
grub_register_variable_hook(g_global_vars[i].name, ventoy_global_var_read_hook, ventoy_global_var_write_hook);
}
return 0;
}
static ctrl_var_cfg g_ctrl_vars[] =
{
{ "VTOY_WIN11_BYPASS_CHECK", 1 },
{ "VTOY_WIN11_BYPASS_NRO", 1 },
{ "VTOY_LINUX_REMOUNT", 0 },
{ "VTOY_SECONDARY_BOOT_MENU", 1 },
{ NULL, 0 }
};
static const char * ventoy_ctrl_var_read_hook(struct grub_env_var *var, const char *val)
{
int i;
for (i = 0; g_ctrl_vars[i].name; i++)
{
if (grub_strcmp(g_ctrl_vars[i].name, var->name) == 0)
{
return g_ctrl_vars[i].value ? "1" : "0";
}
}
return val;
}
static char * ventoy_ctrl_var_write_hook(struct grub_env_var *var, const char *val)
{
int i;
for (i = 0; g_ctrl_vars[i].name; i++)
{
if (grub_strcmp(g_ctrl_vars[i].name, var->name) == 0)
{
if (val && val[0] == '1' && val[1] == 0)
{
g_ctrl_vars[i].value = 1;
return grub_strdup("1");
}
else
{
g_ctrl_vars[i].value = 0;
return grub_strdup("0");
}
}
}
return grub_strdup(val);
}
int ventoy_ctrl_var_init(void)
{
int i;
for (i = 0; g_ctrl_vars[i].name; i++)
{
ventoy_env_export(g_ctrl_vars[i].name, g_ctrl_vars[i].value ? "1" : "0");
grub_register_variable_hook(g_ctrl_vars[i].name, ventoy_ctrl_var_read_hook, ventoy_ctrl_var_write_hook);
}
return 0;
}
GRUB_MOD_INIT(ventoy) GRUB_MOD_INIT(ventoy)
{ {
ventoy_hwinfo_init();
ventoy_env_init(); ventoy_env_init();
ventoy_arch_mode_init(); ventoy_arch_mode_init();
ventoy_register_all_cmd(); ventoy_register_all_cmd();

View File

@ -0,0 +1,652 @@
/******************************************************************************
* ventoy_browser.c
*
* Copyright (c) 2022, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/device.h>
#include <grub/term.h>
#include <grub/partition.h>
#include <grub/file.h>
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/datetime.h>
#include <grub/i18n.h>
#include <grub/net.h>
#include <grub/time.h>
#include <grub/ventoy.h>
#include "ventoy_def.h"
GRUB_MOD_LICENSE ("GPLv3+");
#define BROWSER_MENU_BUF 65536
static const char *g_vtoy_dev = NULL;
static grub_fs_t g_menu_fs = NULL;
static char *g_menu_device = NULL;
static grub_device_t g_menu_dev = NULL;
static char g_menu_path_buf[1024];
static int g_menu_path_len = 0;
static browser_node *g_browser_list = NULL;
static int ventoy_browser_strcmp(char *str1, char *str2)
{
char *s1, *s2;
int c1 = 0;
int c2 = 0;
for (s1 = str1, s2 = str2; *s1 && *s2; s1++, s2++)
{
c1 = *s1;
c2 = *s2;
if (0 == g_sort_case_sensitive)
{
if (grub_islower(c1))
{
c1 = c1 - 'a' + 'A';
}
if (grub_islower(c2))
{
c2 = c2 - 'a' + 'A';
}
}
if (c1 != c2)
{
break;
}
}
return (c1 - c2);
}
static int ventoy_browser_mbuf_alloc(browser_mbuf *mbuf)
{
grub_memset(mbuf, 0, sizeof(browser_mbuf));
mbuf->buf = grub_malloc(BROWSER_MENU_BUF);
if (!mbuf->buf)
{
return 0;
}
mbuf->pos = 0;
mbuf->max = BROWSER_MENU_BUF;
return 1;
}
static inline void ventoy_browser_mbuf_free(browser_mbuf *mbuf)
{
if (mbuf)
grub_check_free(mbuf->buf)
}
static inline int ventoy_browser_mbuf_extend(browser_mbuf *mbuf)
{
if (mbuf->max - mbuf->pos <= VTOY_SIZE_1KB)
{
mbuf->max += BROWSER_MENU_BUF;
mbuf->buf = grub_realloc(mbuf->buf, mbuf->max);
}
return 0;
}
static browser_node * ventoy_browser_find_top_node(int dir)
{
browser_node *node = NULL;
browser_node *sel = NULL;
for (node = g_browser_list; node; node = node->next)
{
if (node->dir == dir)
{
if (sel)
{
if (ventoy_browser_strcmp(sel->filename, node->filename) > 0)
{
sel = node;
}
}
else
{
sel = node;
}
}
}
return sel;
}
static int ventoy_browser_iterate_partition(struct grub_disk *disk, const grub_partition_t partition, void *data)
{
char partname[64];
char title[256];
grub_device_t dev;
grub_fs_t fs;
char *Label = NULL;
browser_mbuf *mbuf = (browser_mbuf *)data;
(void)data;
if (partition->number == 1 && g_vtoy_dev && grub_strcmp(disk->name, g_vtoy_dev) == 0)
{
return 0;
}
grub_snprintf(partname, sizeof(partname) - 1, "%s,%d", disk->name, partition->number + 1);
dev = grub_device_open(partname);
if (!dev)
{
return 0;
}
fs = grub_fs_probe(dev);
if (!fs)
{
grub_device_close(dev);
return 0;
}
fs->fs_label(dev, &Label);
if (ventoy_check_file_exist("(%s)/.ventoyignore", partname))
{
return 0;
}
if (g_tree_view_menu_style == 0)
{
grub_snprintf(title, sizeof(title), "%-10s (%s,%s%d) [%s] %s %s",
"DISK", disk->name, partition->msdostype == 0xee ? "gpt" : "msdos",
partition->number + 1, (Label ? Label : ""), fs->name,
grub_get_human_size(partition->len << disk->log_sector_size, GRUB_HUMAN_SIZE_SHORT));
}
else
{
grub_snprintf(title, sizeof(title), "(%s,%s%d) [%s] %s %s",
disk->name, partition->msdostype == 0xee ? "gpt" : "msdos",
partition->number + 1, (Label ? Label : ""), fs->name,
grub_get_human_size(partition->len << disk->log_sector_size, GRUB_HUMAN_SIZE_SHORT));
}
if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max)
{
browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n"
" echo \"unsupported file system type!\" \n"
" ventoy_pause\n"
"}\n",
title);
}
else
{
browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n"
" vt_browser_dir %s,%d 0x%lx /\n"
"}\n",
title, disk->name, partition->number + 1, (ulong)fs);
}
ventoy_browser_mbuf_extend(mbuf);
return 0;
}
static int ventoy_browser_iterate_disk(const char *name, void *data)
{
grub_disk_t disk;
if (name[0] != 'h')
{
return 0;
}
disk = grub_disk_open(name);
if (disk)
{
grub_partition_iterate(disk, ventoy_browser_iterate_partition, data);
grub_disk_close(disk);
}
return 0;
}
static int ventoy_browser_valid_dirname(const char *name, int len)
{
if ((len == 1 && name[0] == '.') ||
(len == 2 && name[0] == '.' && name[1] == '.'))
{
return 0;
}
if (!ventoy_img_name_valid(name, len))
{
return 0;
}
if (g_filt_trash_dir)
{
if (0 == grub_strncmp(name, ".trash-", 7) ||
0 == grub_strcmp(name, ".Trashes"))
{
return 0;
}
}
if (name[0] == '$')
{
if (0 == grub_strncmp(name, "$RECYCLE.BIN", 12) ||
0 == grub_strncasecmp(name, "$Extend", 7))
{
return 0;
}
}
if (len == 25 && grub_strncmp(name, "System Volume Information", 25) == 0)
{
return 0;
}
return 1;
}
static int ventoy_browser_valid_filename(const char *filename, int len, int *type)
{
if (len < 4)
{
return 0;
}
if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso"))
{
*type = img_type_iso;
}
else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim")))
{
*type = img_type_wim;
}
else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") ||
(len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx"))))
{
*type = img_type_vhd;
}
#ifdef GRUB_MACHINE_EFI
else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi"))
{
*type = img_type_efi;
}
#endif
else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img"))
{
if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0)
{
if (grub_strncmp(filename + 7, "wimboot", 7) == 0 ||
grub_strncmp(filename + 7, "vhdboot", 7) == 0)
{
return 0;
}
}
*type = img_type_img;
}
else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy"))
{
*type = img_type_vtoy;
}
else
{
return 0;
}
if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_')
{
return 0;
}
return 1;
}
static int ventoy_browser_check_ignore(const char *device, const char *root, const char *dir)
{
grub_file_t file;
char fullpath[1024] = {0};
grub_snprintf(fullpath, 1023, "(%s)%s/%s/.ventoyignore", device, root, dir);
file = grub_file_open(fullpath, GRUB_FILE_TYPE_NONE);
if (!file)
{
grub_errno = 0;
return 0;
}
else
{
grub_file_close(file);
return 1;
}
}
static int ventoy_browser_iterate_dir(const char *filename, const struct grub_dirhook_info *info, void *data)
{
int type;
int len;
browser_node *node;
(void)data;
len = grub_strlen(filename);
if (info->dir)
{
if (!ventoy_browser_valid_dirname(filename, len))
{
return 0;
}
if (ventoy_browser_check_ignore(g_menu_device, g_menu_path_buf, filename))
{
return 0;
}
node = grub_zalloc(sizeof(browser_node));
if (!node)
{
return 0;
}
node->dir = 1;
grub_strncpy(node->filename, filename, sizeof(node->filename));
if (g_tree_view_menu_style == 0)
{
grub_snprintf(node->menuentry, sizeof(node->menuentry),
"menuentry \"%-10s [%s]\" --class=vtoydir {\n"
" vt_browser_dir %s 0x%lx \"%s/%s\"\n"
"}\n",
"DIR", filename, g_menu_device, (ulong)g_menu_fs, g_menu_path_buf, filename);
}
else
{
grub_snprintf(node->menuentry, sizeof(node->menuentry),
"menuentry \"[%s]\" --class=vtoydir {\n"
" vt_browser_dir %s 0x%lx \"%s/%s\"\n"
"}\n",
filename, g_menu_device, (ulong)g_menu_fs, g_menu_path_buf, filename);
}
}
else
{
grub_uint64_t fsize = info->size;
if (!ventoy_browser_valid_filename(filename, len, &type))
{
return 0;
}
if (grub_file_is_vlnk_suffix(filename, len))
{
return 0;
}
node = grub_zalloc(sizeof(browser_node));
if (!node)
{
return 0;
}
if (fsize == 0)
{
struct grub_file file;
grub_memset(&file, 0, sizeof(file));
file.device = g_menu_dev;
grub_snprintf(node->menuentry, sizeof(node->menuentry), "%s/%s", g_menu_path_buf, filename);
if (g_menu_fs->fs_open(&file, node->menuentry) == GRUB_ERR_NONE)
{
fsize = file.size;
g_menu_fs->fs_close(&file);
}
}
node->dir = 0;
grub_strncpy(node->filename, filename, sizeof(node->filename));
if (g_tree_view_menu_style == 0)
{
grub_snprintf(node->menuentry, sizeof(node->menuentry),
"menuentry \"%-10s %s\" --class=%s {\n"
" vt_set_fake_vlnk \"(%s)%s/%s\" %s %llu\n"
" %s_common_menuentry\n"
" vt_reset_fake_vlnk\n"
"}\n",
grub_get_human_size(fsize, GRUB_HUMAN_SIZE_SHORT), filename, g_menu_class[type],
g_menu_device, g_menu_path_buf, filename, g_menu_prefix[type], (ulonglong)fsize,
g_menu_prefix[type]);
}
else
{
grub_snprintf(node->menuentry, sizeof(node->menuentry),
"menuentry \"%s\" --class=%s {\n"
" vt_set_fake_vlnk \"(%s)%s/%s\" %s %llu\n"
" %s_common_menuentry\n"
" vt_reset_fake_vlnk\n"
"}\n",
filename, g_menu_class[type],
g_menu_device, g_menu_path_buf, filename, g_menu_prefix[type], (ulonglong)fsize,
g_menu_prefix[type]);
}
}
node->prev = NULL;
node->next = g_browser_list;
if (g_browser_list)
{
g_browser_list->prev = node;
}
g_browser_list = node;
return 0;
}
static grub_err_t ventoy_browser_iso_part(void)
{
char cfgfile[64];
char *buffer = NULL;
int pos = 0;
int buflen = 0;
int cfglen = 0;
cfglen = g_tree_script_pos - g_tree_script_pre;
buflen = cfglen + 512;
buffer = grub_malloc(buflen);
if (!buffer)
{
return 1;
}
if (g_tree_view_menu_style == 0)
{
pos = grub_snprintf(buffer, buflen, "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", "<--");
}
else
{
pos = grub_snprintf(buffer, buflen, "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n");
}
grub_memcpy(buffer + pos, g_tree_script_buf + g_tree_script_pre, cfglen);
pos += cfglen;
grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)buffer, pos);
grub_script_execute_sourcecode(cfgfile);
grub_free(buffer);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i;
grub_fs_t fs;
grub_device_t dev;
char cfgfile[64];
browser_node *node;
browser_mbuf mbuf;
(void)ctxt;
(void)argc;
if (args[2][0] == '/' && args[2][1] == 0)
{
grub_snprintf(cfgfile, sizeof(cfgfile), "(%s)", args[0]);
if (grub_strcmp(cfgfile, g_iso_path) == 0)
{
return ventoy_browser_iso_part();
}
}
if (!ventoy_browser_mbuf_alloc(&mbuf))
{
return 1;
}
fs = (grub_fs_t)grub_strtoul(args[1], NULL, 16);
if (!fs)
{
debug("Invalid fs %s\n", args[1]);
return 1;
}
dev = grub_device_open(args[0]);
if (!dev)
{
debug("Failed to open device %s\n", args[0]);
return 1;
}
g_menu_fs = fs;
g_menu_device = args[0];
g_menu_dev = dev;
g_browser_list = NULL;
if (args[2][0] == '/' && args[2][1] == 0)
{
g_menu_path_len = 0;
g_menu_path_buf[0] = 0;
fs->fs_dir(dev, "/", ventoy_browser_iterate_dir, NULL);
}
else
{
g_menu_path_len = grub_snprintf(g_menu_path_buf, sizeof(g_menu_path_buf), "%s", args[2]);
fs->fs_dir(dev, g_menu_path_buf, ventoy_browser_iterate_dir, NULL);
}
grub_device_close(dev);
if (g_tree_view_menu_style == 0)
{
browser_ssprintf(&mbuf, "menuentry \"%-10s [(%s)%s/..]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", "<--", args[0], g_menu_path_buf);
}
else
{
browser_ssprintf(&mbuf, "menuentry \"[(%s)%s/..]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", args[0], g_menu_path_buf);
}
for (i = 1; i >= 0; i--)
{
while (1)
{
node = ventoy_browser_find_top_node(i);
if (node)
{
browser_ssprintf(&mbuf, "%s", node->menuentry);
ventoy_browser_mbuf_extend(&mbuf);
if (node->prev)
{
node->prev->next = node->next;
}
if (node->next)
{
node->next->prev = node->prev;
}
if (node == g_browser_list)
{
g_browser_list = node->next;
}
grub_free(node);
}
else
{
break;
}
}
}
g_browser_list = NULL;
grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos);
grub_script_execute_sourcecode(cfgfile);
ventoy_browser_mbuf_free(&mbuf);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args)
{
char cfgfile[64];
browser_mbuf mbuf;
(void)ctxt;
(void)argc;
(void)args;
if (!ventoy_browser_mbuf_alloc(&mbuf))
{
return 1;
}
g_vtoy_dev = grub_env_get("vtoydev");
if (g_tree_view_menu_style == 0)
{
browser_ssprintf(&mbuf, "menuentry \"%-10s [%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n", "<--",
ventoy_get_vmenu_title("VTLANG_BROWER_RETURN"));
}
else
{
browser_ssprintf(&mbuf, "menuentry \"[%s]\" --class=\"vtoyret\" VTOY_RET {\n "
" echo 'return ...' \n}\n",
ventoy_get_vmenu_title("VTLANG_BROWER_RETURN"));
}
grub_disk_dev_iterate(ventoy_browser_iterate_disk, &mbuf);
grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos);
grub_script_execute_sourcecode(cfgfile);
ventoy_browser_mbuf_free(&mbuf);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}

File diff suppressed because it is too large Load Diff

View File

@ -29,17 +29,23 @@
#define VTOY_FILT_MIN_FILE_SIZE 32768 #define VTOY_FILT_MIN_FILE_SIZE 32768
#define VTOY_LINUX_SYSTEMD_MENU_MAX_BUF 16384
#define VTOY_SIZE_1GB 1073741824 #define VTOY_SIZE_1GB 1073741824
#define VTOY_SIZE_1MB (1024 * 1024) #define VTOY_SIZE_1MB (1024 * 1024)
#define VTOY_SIZE_2MB (2 * 1024 * 1024) #define VTOY_SIZE_2MB (2 * 1024 * 1024)
#define VTOY_SIZE_4MB (4 * 1024 * 1024) #define VTOY_SIZE_4MB (4 * 1024 * 1024)
#define VTOY_SIZE_512KB (512 * 1024) #define VTOY_SIZE_512KB (512 * 1024)
#define VTOY_SIZE_1KB 1024 #define VTOY_SIZE_1KB 1024
#define VTOY_SIZE_32KB (32 * 1024)
#define VTOY_SIZE_128KB (128 * 1024)
#define JSON_SUCCESS 0 #define JSON_SUCCESS 0
#define JSON_FAILED 1 #define JSON_FAILED 1
#define JSON_NOT_FOUND 2 #define JSON_NOT_FOUND 2
#define WINDATA_FLAG_TEMPLATE 1
#define ulong unsigned long #define ulong unsigned long
#define ulonglong unsigned long long #define ulonglong unsigned long long
@ -56,6 +62,8 @@
#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!" #define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
#define VTOY_CHKSUM_NUM 4
#define VTOY_PLAT_I386_UEFI 0x49413332 #define VTOY_PLAT_I386_UEFI 0x49413332
#define VTOY_PLAT_ARM64_UEFI 0x41413634 #define VTOY_PLAT_ARM64_UEFI 0x41413634
#define VTOY_PLAT_X86_64_UEFI 0x55454649 #define VTOY_PLAT_X86_64_UEFI 0x55454649
@ -71,6 +79,10 @@
#define VTOY_ARCH_CPIO "ventoy_x86.cpio" #define VTOY_ARCH_CPIO "ventoy_x86.cpio"
#endif #endif
#define ventoy_left_key "VTLE_LFT"
#define ventoy_top_key "VTLE_TOP"
#define ventoy_color_key "VTLE_CLR"
#define ventoy_varg_4(arg) arg[0], arg[1], arg[2], arg[3] #define ventoy_varg_4(arg) arg[0], arg[1], arg[2], arg[3]
#define ventoy_varg_8(arg) arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7] #define ventoy_varg_8(arg) arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]
@ -83,6 +95,38 @@
return (err);\ return (err);\
} }
#define VTOY_APPEND_NEWBUF(buf) \
{\
char *__c = buf;\
while (*__c)\
{\
newbuf[pos++] = *__c;\
__c++;\
}\
}
#define VTOY_SKIP_SPACE(s) \
while (ventoy_isspace(*s)) \
{\
s++;\
}
#define VTOY_SKIP_SPACE_NEXT(s, initial) \
s += initial;\
while (ventoy_isspace(*s)) \
{\
s++;\
}
#define VTOY_SKIP_SPACE_NEXT_EX(s, base, initial) \
s = base + initial;\
while (ventoy_isspace(*s)) \
{\
s++;\
}
#define VTOY_GOTO_END(v) ret = v; goto end
typedef enum VTOY_FILE_FLT typedef enum VTOY_FILE_FLT
{ {
VTOY_FILE_FLT_ISO = 0, /* .iso */ VTOY_FILE_FLT_ISO = 0, /* .iso */
@ -304,6 +348,7 @@ extern ventoy_guid g_ventoy_guid;
extern ventoy_img_chunk_list g_img_chunk_list; extern ventoy_img_chunk_list g_img_chunk_list;
extern ventoy_img_chunk_list g_wimiso_chunk_list; extern ventoy_img_chunk_list g_wimiso_chunk_list;
extern char *g_wimiso_path; extern char *g_wimiso_path;
extern grub_uint32_t g_wimiso_size;
extern char g_arch_mode_suffix[64]; extern char g_arch_mode_suffix[64];
extern const char *g_menu_prefix[img_type_max]; extern const char *g_menu_prefix[img_type_max];
@ -311,8 +356,18 @@ extern int g_ventoy_debug;
void ventoy_debug(const char *fmt, ...); void ventoy_debug(const char *fmt, ...);
#define debug(fmt, args...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, ##args) #define debug(fmt, args...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, ##args)
#define vtoy_ssprintf(buf, pos, fmt, ...) \ #define vtoy_ssprintf(buf, pos, fmt, args...) \
pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, __VA_ARGS__) pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, ##args)
#define vtoy_len_ssprintf(buf, pos, len, fmt, args...) \
pos += grub_snprintf(buf + pos, len - pos, fmt, ##args)
#define browser_ssprintf(mbuf, fmt, args...) \
(mbuf)->pos += grub_snprintf((mbuf)->buf + (mbuf)->pos, (mbuf)->max - (mbuf)->pos, fmt, ##args)
#define vtoy_dummy_menuentry(buf, pos, len, title, class) \
vtoy_len_ssprintf(buf, pos, len, "menuentry \"%s\" --class=\"%s\" {\n echo \"\"\n}\n", title, class)
#define FLAG_HEADER_RESERVED 0x00000001 #define FLAG_HEADER_RESERVED 0x00000001
#define FLAG_HEADER_COMPRESSION 0x00000002 #define FLAG_HEADER_COMPRESSION 0x00000002
@ -483,6 +538,7 @@ typedef struct wim_tail
grub_uint8_t *jump_bin_data; grub_uint8_t *jump_bin_data;
grub_uint32_t bin_raw_len; grub_uint32_t bin_raw_len;
grub_uint32_t bin_align_len; grub_uint32_t bin_align_len;
grub_uint32_t windata_flag;
grub_uint8_t *new_meta_data; grub_uint8_t *new_meta_data;
grub_uint32_t new_meta_len; grub_uint32_t new_meta_len;
@ -582,6 +638,12 @@ typedef struct chk_case_fs_dir
grub_fs_t fs; grub_fs_t fs;
}chk_case_fs_dir; }chk_case_fs_dir;
int ventoy_str_all_digit(const char *str);
int ventoy_str_all_alnum(const char *str);
int ventoy_str_len_alnum(const char *str, int len);
char * ventoy_str_basename(char *path);
grub_err_t ventoy_env_int_set(const char *name, int value);
int ventoy_str_chrcnt(const char *str, char c);
int ventoy_strcmp(const char *pattern, const char *str); int ventoy_strcmp(const char *pattern, const char *str);
int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n); int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n);
void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param); void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param);
@ -593,6 +655,8 @@ grub_err_t ventoy_cmd_clear_initrd_list(grub_extcmd_context_t ctxt, int argc, ch
grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file); grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file);
int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector); int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector);
grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_linux_systemd_menu(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_linux_limine_menu(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args);
@ -604,7 +668,6 @@ grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **
int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name); int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name);
grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...);
grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...); grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...);
int ventoy_is_file_exist(const char *fmt, ...);
int ventoy_is_dir_exist(const char *fmt, ...); int ventoy_is_dir_exist(const char *fmt, ...);
int ventoy_fill_data(grub_uint32_t buflen, char *buffer); 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_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args);
@ -614,6 +677,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_is_standard_winiso(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_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_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_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args);
@ -826,6 +890,7 @@ typedef struct ventoy_video_mode
typedef struct file_fullpath typedef struct file_fullpath
{ {
char path[256]; char path[256];
int vlnk_add;
}file_fullpath; }file_fullpath;
typedef struct theme_list typedef struct theme_list
@ -848,6 +913,9 @@ typedef struct install_template
int templatenum; int templatenum;
file_fullpath *templatepath; file_fullpath *templatepath;
char *filebuf;
int filelen;
struct install_template *next; struct install_template *next;
}install_template; }install_template;
@ -937,7 +1005,7 @@ typedef struct custom_boot
struct custom_boot *next; struct custom_boot *next;
}custom_boot; }custom_boot;
#define vtoy_max_replace_file_size (2 * 1024 * 1024) #define vtoy_max_replace_file_size (1024 * 1024)
typedef struct conf_replace typedef struct conf_replace
{ {
int pathlen; int pathlen;
@ -1005,6 +1073,7 @@ typedef struct menu_password
}menu_password; }menu_password;
extern int g_ventoy_menu_esc; extern int g_ventoy_menu_esc;
extern int g_ventoy_secondary_menu_on;
extern int g_ventoy_suppress_esc; extern int g_ventoy_suppress_esc;
extern int g_ventoy_suppress_esc_default; extern int g_ventoy_suppress_esc_default;
extern int g_ventoy_last_entry; extern int g_ventoy_last_entry;
@ -1014,20 +1083,26 @@ extern int g_ventoy_grub2_mode;
extern int g_ventoy_wimboot_mode; extern int g_ventoy_wimboot_mode;
extern int g_ventoy_iso_uefi_drv; extern int g_ventoy_iso_uefi_drv;
extern int g_ventoy_case_insensitive; extern int g_ventoy_case_insensitive;
extern int g_ventoy_fn_mutex;
extern grub_uint8_t g_ventoy_chain_type; extern grub_uint8_t g_ventoy_chain_type;
extern int g_vhdboot_enable; extern int g_vhdboot_enable;
extern int g_default_menu_mode;
extern char g_ventoy_hotkey_tip[256];
extern int g_ventoy_menu_refresh;
#define VENTOY_IMG_WHITE_LIST 1 #define VENTOY_IMG_WHITE_LIST 1
#define VENTOY_IMG_BLACK_LIST 2 #define VENTOY_IMG_BLACK_LIST 2
extern int g_plugin_image_list; extern int g_plugin_image_list;
extern ventoy_gpt_info *g_ventoy_part_info; extern ventoy_gpt_info *g_ventoy_part_info;
extern grub_uint64_t g_conf_replace_offset; extern int g_conf_replace_count;
extern grub_uint64_t g_conf_replace_offset[VTOY_MAX_CONF_REPLACE];
extern grub_uint64_t g_svd_replace_offset; extern grub_uint64_t g_svd_replace_offset;
extern conf_replace *g_conf_replace_node; extern conf_replace *g_conf_replace_node[VTOY_MAX_CONF_REPLACE];
extern grub_uint8_t *g_conf_replace_new_buf; extern grub_uint8_t *g_conf_replace_new_buf[VTOY_MAX_CONF_REPLACE];
extern int g_conf_replace_new_len; extern int g_conf_replace_new_len[VTOY_MAX_CONF_REPLACE];
extern int g_conf_replace_new_len_align; extern int g_conf_replace_new_len_align[VTOY_MAX_CONF_REPLACE];
extern int g_ventoy_disk_bios_id;
extern grub_uint64_t g_ventoy_disk_size; extern grub_uint64_t g_ventoy_disk_size;
extern grub_uint64_t g_ventoy_disk_part_size[2]; extern grub_uint64_t g_ventoy_disk_part_size[2];
extern grub_uint32_t g_ventoy_plat_data; extern grub_uint32_t g_ventoy_plat_data;
@ -1054,15 +1129,15 @@ extern grub_uint32_t g_ventoy_plat_data;
void ventoy_str_tolower(char *str); void ventoy_str_tolower(char *str);
void ventoy_str_toupper(char *str); void ventoy_str_toupper(char *str);
char * ventoy_get_line(char *start); char * ventoy_get_line(char *start);
char *ventoy_str_last(char *str, char ch);
int ventoy_cmp_img(img_info *img1, img_info *img2); int ventoy_cmp_img(img_info *img1, img_info *img2);
void ventoy_swap_img(img_info *img1, img_info *img2); void ventoy_swap_img(img_info *img1, img_info *img2);
char * ventoy_plugin_get_cur_install_template(const char *isopath); char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur);
install_template * ventoy_plugin_find_install_template(const char *isopath); install_template * ventoy_plugin_find_install_template(const char *isopath);
persistence_config * ventoy_plugin_find_persistent(const char *isopath); persistence_config * ventoy_plugin_find_persistent(const char *isopath);
grub_uint64_t ventoy_get_vtoy_partsize(int part); grub_uint64_t ventoy_get_vtoy_partsize(int part);
void ventoy_plugin_dump_injection(void); void ventoy_plugin_dump_injection(void);
void ventoy_plugin_dump_auto_install(void); 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); int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list);
const char * ventoy_plugin_get_injection(const char *isopath); const char * ventoy_plugin_get_injection(const char *isopath);
const char * ventoy_plugin_get_menu_alias(int type, const char *isopath); const char * ventoy_plugin_get_menu_alias(int type, const char *isopath);
@ -1070,7 +1145,7 @@ const menu_tip * ventoy_plugin_get_menu_tip(int type, const char *isopath);
const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path); const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path);
int ventoy_plugin_check_memdisk(const char *isopath); int ventoy_plugin_check_memdisk(const char *isopath);
int ventoy_plugin_get_image_list_index(int type, const char *name); int ventoy_plugin_get_image_list_index(int type, const char *name);
conf_replace * ventoy_plugin_find_conf_replace(const char *iso); int ventoy_plugin_find_conf_replace(const char *iso, conf_replace *nodes[VTOY_MAX_CONF_REPLACE]);
dud * ventoy_plugin_find_dud(const char *iso); dud * ventoy_plugin_find_dud(const char *iso);
int ventoy_plugin_load_dud(dud *node, const char *isopart); int ventoy_plugin_load_dud(dud *node, const char *isopart);
int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
@ -1085,10 +1160,13 @@ grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, in
grub_err_t ventoy_cmd_collect_wim_patch(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_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); grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_sel_winpe_wim(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature); int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature);
grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_ko_fillmap(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args);
@ -1153,5 +1231,91 @@ struct g_ventoy_map{
}; };
#pragma pack() #pragma pack()
typedef struct ventoy_vlnk_part
{
grub_uint32_t disksig;
grub_uint64_t partoffset;
char disk[64];
char device[64];
grub_device_t dev;
grub_fs_t fs;
int probe;
struct ventoy_vlnk_part *next;
}ventoy_vlnk_part;
typedef struct browser_mbuf
{
int max;
int pos;
char *buf;
}browser_mbuf;
typedef struct browser_node
{
int dir;
char menuentry[1024];
char filename[512];
struct browser_node *prev;
struct browser_node *next;
}browser_node;
typedef struct var_node
{
char var[128];
char val[256];
struct var_node *next;
}var_node;
typedef struct systemd_menu_ctx
{
char *dev;
char *buf;
int pos;
int len;
}systemd_menu_ctx;
typedef struct global_var_cfg
{
const char *name;
const char *defval;
char *value;
}global_var_cfg;
typedef struct ctrl_var_cfg
{
const char *name;
int value;
}ctrl_var_cfg;
#define vtoy_check_goto_out(p) if (!p) goto out
extern char *g_tree_script_buf;
extern int g_tree_script_pos;
extern int g_tree_script_pre;
extern int g_tree_view_menu_style;
extern int g_sort_case_sensitive;
extern int g_wimboot_enable;
extern int g_filt_dot_underscore_file;
extern int g_filt_trash_dir;
extern int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT];
extern const char *g_menu_class[img_type_max];
extern char g_iso_path[256];
int ventoy_add_vlnk_file(char *dir, const char *name);
grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args);
int ventoy_get_fs_type(const char *fs);
int ventoy_img_name_valid(const char *filename, grub_size_t namelen);
void * ventoy_alloc_chain(grub_size_t size);
int ventoy_plugin_load_menu_lang(int init, const char *lang);
const char *ventoy_get_vmenu_title(const char *vMenu);
grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args);
extern int ventoy_menu_push_key(int code);
int ventoy_ctrl_var_init(void);
int ventoy_global_var_init(void);
grub_err_t ventoy_cmd_push_menulang(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_pop_menulang(grub_extcmd_context_t ctxt, int argc, char **args);
#endif /* __VENTOY_DEF_H__ */ #endif /* __VENTOY_DEF_H__ */

View File

@ -177,10 +177,7 @@ static grub_err_t ventoy_isolinux_initrd_collect(grub_file_t file, const char *p
{ {
nextline = ventoy_get_line(start); nextline = ventoy_get_line(start);
while (ventoy_isspace(*start)) VTOY_SKIP_SPACE(start);
{
start++;
}
offset = 7; // strlen("initrd=") or "INITRD " or "initrd " offset = 7; // strlen("initrd=") or "INITRD " or "initrd "
pos = grub_strstr(start, "initrd="); pos = grub_strstr(start, "initrd=");
@ -333,12 +330,84 @@ end:
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
static int ventoy_linux_initrd_collect_hook(const char *filename, const struct grub_dirhook_info *info, void *data)
{
int len;
initrd_info *img = NULL;
(void)data;
if (0 == info->dir)
{
if (grub_strncmp(filename, "initrd", 6) == 0)
{
len = (int)grub_strlen(filename);
if (grub_strcmp(filename + len - 4, ".img") == 0)
{
img = grub_zalloc(sizeof(initrd_info));
if (img)
{
grub_snprintf(img->name, sizeof(img->name), "/boot/%s", filename);
if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
{
grub_free(img);
}
else
{
if (g_initrd_img_list)
{
img->prev = g_initrd_img_tail;
g_initrd_img_tail->next = img;
}
else
{
g_initrd_img_list = img;
}
g_initrd_img_tail = img;
g_initrd_img_count++;
}
}
}
}
}
return 0;
}
static int ventoy_linux_collect_boot_initrds(void)
{
grub_fs_t fs;
grub_device_t dev = NULL;
dev = grub_device_open("loop");
if (!dev)
{
debug("failed to open device loop\n");
goto end;
}
fs = grub_fs_probe(dev);
if (!fs)
{
debug("failed to probe fs %d\n", grub_errno);
goto end;
}
fs->fs_dir(dev, "/boot", ventoy_linux_initrd_collect_hook, NULL);
end:
return 0;
}
static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName) static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
{ {
int i = 0; int i = 0;
int len = 0; int len = 0;
int dollar = 0; int dollar = 0;
int quotation = 0; int quotation = 0;
int initrd_dollar = 0;
grub_file_t file = NULL; grub_file_t file = NULL;
char *buf = NULL; char *buf = NULL;
char *start = NULL; char *start = NULL;
@ -366,10 +435,7 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
{ {
nextline = ventoy_get_line(start); nextline = ventoy_get_line(start);
while (ventoy_isspace(*start)) VTOY_SKIP_SPACE(start);
{
start++;
}
if (grub_strncmp(start, "initrd", 6) != 0) if (grub_strncmp(start, "initrd", 6) != 0)
{ {
@ -382,10 +448,7 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
start++; start++;
} }
while (ventoy_isspace(*start)) VTOY_SKIP_SPACE(start);
{
start++;
}
if (*start == '"') if (*start == '"')
{ {
@ -421,6 +484,19 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
debug("Remove quotation <%s>\n", img->name); debug("Remove quotation <%s>\n", img->name);
} }
/* special process for /boot/initrd$XXX.img */
if (dollar == 1)
{
if (grub_strncmp(img->name, "/boot/initrd$", 13) == 0)
{
len = (int)grub_strlen(img->name);
if (grub_strcmp(img->name + len - 4, ".img") == 0)
{
initrd_dollar++;
}
}
}
if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
{ {
grub_free(img); grub_free(img);
@ -443,10 +519,7 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
if (*start == ' ' || *start == '\t') if (*start == ' ' || *start == '\t')
{ {
while (ventoy_isspace(*start)) VTOY_SKIP_SPACE(start);
{
start++;
}
} }
else else
{ {
@ -458,6 +531,12 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
grub_free(buf); grub_free(buf);
grub_file_close(file); grub_file_close(file);
if (initrd_dollar > 0 && grub_strncmp(fileName, "(loop)/", 7) == 0)
{
debug("collect initrd variable %d\n", initrd_dollar);
ventoy_linux_collect_boot_initrds();
}
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
@ -654,12 +733,19 @@ int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, co
static grub_uint32_t ventoy_linux_get_virt_chunk_count(void) static grub_uint32_t ventoy_linux_get_virt_chunk_count(void)
{ {
int i;
grub_uint32_t count = g_valid_initrd_count; grub_uint32_t count = g_valid_initrd_count;
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{
for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{ {
count++; count++;
} }
}
}
if (g_append_ext_sector > 0) if (g_append_ext_sector > 0)
{ {
@ -671,13 +757,20 @@ static grub_uint32_t ventoy_linux_get_virt_chunk_count(void)
static grub_uint32_t ventoy_linux_get_virt_chunk_size(void) static grub_uint32_t ventoy_linux_get_virt_chunk_size(void)
{ {
int i;
grub_uint32_t size; grub_uint32_t size;
size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count; size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count;
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{ {
size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align; for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{
size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align[i];
}
}
} }
if (g_append_ext_sector > 0) if (g_append_ext_sector > 0)
@ -690,6 +783,7 @@ static grub_uint32_t ventoy_linux_get_virt_chunk_size(void)
static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
{ {
int i = 0;
int id = 0; int id = 0;
int virtid = 0; int virtid = 0;
initrd_info *node; initrd_info *node;
@ -699,6 +793,7 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_
grub_uint32_t initrd_secs; grub_uint32_t initrd_secs;
char *override; char *override;
ventoy_virt_chunk *cur; ventoy_virt_chunk *cur;
ventoy_grub_param_file_replace *replace = NULL;
char name[32]; char name[32];
override = (char *)chain + chain->virt_chunk_offset; override = (char *)chain + chain->virt_chunk_offset;
@ -764,9 +859,13 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_
virtid++; virtid++;
} }
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{ {
cpio_secs = g_conf_replace_new_len_align / 2048; for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{
cpio_secs = g_conf_replace_new_len_align[i] / 2048;
cur->mem_sector_start = sector; cur->mem_sector_start = sector;
cur->mem_sector_end = cur->mem_sector_start + cpio_secs; cur->mem_sector_end = cur->mem_sector_start + cpio_secs;
@ -775,32 +874,42 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_
cur->remap_sector_end = 0; cur->remap_sector_end = 0;
cur->org_sector_start = 0; cur->org_sector_start = 0;
grub_memcpy(override + offset, g_conf_replace_new_buf, g_conf_replace_new_len); grub_memcpy(override + offset, g_conf_replace_new_buf[i], g_conf_replace_new_len[i]);
chain->virt_img_size_in_bytes += g_conf_replace_new_len_align; chain->virt_img_size_in_bytes += g_conf_replace_new_len_align[i];
if (g_grub_param->img_replace.magic == GRUB_IMG_REPLACE_MAGIC) replace = g_grub_param->img_replace + i;
if (replace->magic == GRUB_IMG_REPLACE_MAGIC)
{ {
g_grub_param->img_replace.new_file_virtual_id = virtid; replace->new_file_virtual_id = virtid;
} }
offset += g_conf_replace_new_len_align; offset += g_conf_replace_new_len_align[i];
sector += cpio_secs; sector += cpio_secs;
cur++; cur++;
virtid++; virtid++;
} }
}
}
return; return;
} }
static grub_uint32_t ventoy_linux_get_override_chunk_count(void) static grub_uint32_t ventoy_linux_get_override_chunk_count(void)
{ {
int i;
grub_uint32_t count = g_valid_initrd_count; grub_uint32_t count = g_valid_initrd_count;
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{
for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{ {
count++; count++;
} }
}
}
if (g_svd_replace_offset > 0) if (g_svd_replace_offset > 0)
{ {
@ -812,12 +921,19 @@ static grub_uint32_t ventoy_linux_get_override_chunk_count(void)
static grub_uint32_t ventoy_linux_get_override_chunk_size(void) static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
{ {
int i;
int count = g_valid_initrd_count; int count = g_valid_initrd_count;
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{
for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{ {
count++; count++;
} }
}
}
if (g_svd_replace_offset > 0) if (g_svd_replace_offset > 0)
{ {
@ -829,6 +945,7 @@ static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override) static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override)
{ {
int i;
initrd_info *node; initrd_info *node;
grub_uint32_t mod; grub_uint32_t mod;
grub_uint32_t newlen; grub_uint32_t newlen;
@ -883,12 +1000,16 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
cur++; cur++;
} }
if (g_conf_replace_offset > 0) if (g_conf_replace_count > 0)
{ {
cur->img_offset = g_conf_replace_offset; for (i = 0; i < g_conf_replace_count; i++)
{
if (g_conf_replace_offset[i] > 0)
{
cur->img_offset = g_conf_replace_offset[i];
cur->override_size = sizeof(ventoy_iso9660_override); cur->override_size = sizeof(ventoy_iso9660_override);
newlen = (grub_uint32_t)(g_conf_replace_new_len); newlen = (grub_uint32_t)(g_conf_replace_new_len[i]);
dirent = (ventoy_iso9660_override *)cur->override_data; dirent = (ventoy_iso9660_override *)cur->override_data;
dirent->first_sector = (grub_uint32_t)sector; dirent->first_sector = (grub_uint32_t)sector;
@ -899,6 +1020,8 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
sector += (dirent->size + 2047) / 2048; sector += (dirent->size + 2047) / 2048;
cur++; cur++;
} }
}
}
if (g_svd_replace_offset > 0) if (g_svd_replace_offset > 0)
{ {
@ -976,6 +1099,7 @@ static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt)
if (filtbysize if (filtbysize
&& (NULL == grub_strstr(node->name, "minirt.gz")) && (NULL == grub_strstr(node->name, "minirt.gz"))
&& (NULL == grub_strstr(node->name, "initrd.xz")) && (NULL == grub_strstr(node->name, "initrd.xz"))
&& (NULL == grub_strstr(node->name, "initrd.gz"))
) )
{ {
if (filt > 0 && file->size <= g_ventoy_cpio_size + 2048) if (filt > 0 && file->size <= g_ventoy_cpio_size + 2048)
@ -1211,6 +1335,7 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
grub_file_t file; grub_file_t file;
grub_file_t archfile; grub_file_t archfile;
grub_file_t tmpfile; grub_file_t tmpfile;
install_template *template_node = NULL;
ventoy_img_chunk_list chunk_list; ventoy_img_chunk_list chunk_list;
(void)ctxt; (void)ctxt;
@ -1257,26 +1382,17 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
persistent_buf = (char *)(chunk_list.chunk); persistent_buf = (char *)(chunk_list.chunk);
} }
template_file = ventoy_plugin_get_cur_install_template(args[1]); template_file = ventoy_plugin_get_cur_install_template(args[1], &template_node);
if (template_file) if (template_file)
{ {
debug("auto install template: <%s>\n", template_file); debug("auto install template: <%s> <addr:%p> <len:%d>\n",
tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file); template_file, template_node->filebuf, template_node->filelen);
if (tmpfile)
{ template_size = template_node->filelen;
debug("auto install script size %d\n", (int)tmpfile->size);
template_size = tmpfile->size;
template_buf = grub_malloc(template_size); template_buf = grub_malloc(template_size);
if (template_buf) if (template_buf)
{ {
grub_file_read(tmpfile, template_buf, template_size); grub_memcpy(template_buf, template_node->filebuf, template_size);
}
grub_file_close(tmpfile);
}
else
{
debug("Failed to open install script %s%s\n", args[2], template_file);
} }
} }
else else
@ -1363,15 +1479,14 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
{ {
headlen = ventoy_cpio_newc_fill_head(buf, template_size, template_buf, "ventoy/autoinstall"); headlen = ventoy_cpio_newc_fill_head(buf, template_size, template_buf, "ventoy/autoinstall");
buf += headlen + ventoy_align(template_size, 4); buf += headlen + ventoy_align(template_size, 4);
grub_check_free(template_buf);
} }
if (persistent_size > 0 && persistent_buf) if (persistent_size > 0 && persistent_buf)
{ {
headlen = ventoy_cpio_newc_fill_head(buf, persistent_size, persistent_buf, "ventoy/ventoy_persistent_map"); headlen = ventoy_cpio_newc_fill_head(buf, persistent_size, persistent_buf, "ventoy/ventoy_persistent_map");
buf += headlen + ventoy_align(persistent_size, 4); buf += headlen + ventoy_align(persistent_size, 4);
grub_check_free(persistent_buf);
grub_free(persistent_buf);
persistent_buf = NULL;
} }
if (injection_size > 0 && injection_buf) if (injection_size > 0 && injection_buf)
@ -1446,7 +1561,6 @@ grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **
grub_uint8_t *bufend; grub_uint8_t *bufend;
cpio_newc_header *head; cpio_newc_header *head;
grub_file_t file; grub_file_t file;
char value[64];
const grub_uint8_t trailler[124] = { const grub_uint8_t trailler[124] = {
0x30, 0x37, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
@ -1518,10 +1632,7 @@ grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **
} }
} }
grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)g_ventoy_cpio_buf); ventoy_memfile_env_set("ventoy_cpio", g_ventoy_cpio_buf, (ulonglong)bufsize);
ventoy_set_env("ventoy_cpio_addr", value);
grub_snprintf(value, sizeof(value), "%d", bufsize);
ventoy_set_env("ventoy_cpio_size", value);
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
@ -1543,7 +1654,6 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
const char *pLastChain = NULL; const char *pLastChain = NULL;
const char *compatible; const char *compatible;
ventoy_chain_head *chain; ventoy_chain_head *chain;
char envbuf[64];
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
@ -1623,18 +1733,15 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
} }
} }
chain = grub_malloc(size); chain = ventoy_alloc_chain(size);
if (!chain) if (!chain)
{ {
grub_printf("Failed to alloc chain memory size %u\n", size); grub_printf("Failed to alloc chain linux memory size %u\n", size);
grub_file_close(file); grub_file_close(file);
return 1; return 1;
} }
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_env_set("vtoy_chain_mem_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_env_set("vtoy_chain_mem_size", envbuf);
grub_memset(chain, 0, sizeof(ventoy_chain_head)); grub_memset(chain, 0, sizeof(ventoy_chain_head));
@ -1685,3 +1792,300 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
static char *ventoy_systemd_conf_tag(char *buf, const char *tag, int optional)
{
int taglen = 0;
char *start = NULL;
char *nextline = NULL;
taglen = grub_strlen(tag);
for (start = buf; start; start = nextline)
{
nextline = ventoy_get_line(start);
VTOY_SKIP_SPACE(start);
if (grub_strncmp(start, tag, taglen) == 0 && (start[taglen] == ' ' || start[taglen] == '\t'))
{
start += taglen;
VTOY_SKIP_SPACE(start);
return start;
}
}
if (optional == 0)
{
debug("tag<%s> NOT found\n", tag);
}
return NULL;
}
static int ventoy_systemd_conf_hook(const char *filename, const struct grub_dirhook_info *info, void *data)
{
int oldpos = 0;
char *tag = NULL;
char *bkbuf = NULL;
char *filebuf = NULL;
grub_file_t file = NULL;
systemd_menu_ctx *ctx = (systemd_menu_ctx *)data;
debug("ventoy_systemd_conf_hook %s\n", filename);
if (info->dir || NULL == grub_strstr(filename, ".conf"))
{
return 0;
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/loader/entries/%s", ctx->dev, filename);
if (!file)
{
return 0;
}
filebuf = grub_zalloc(2 * file->size + 8);
if (!filebuf)
{
goto out;
}
bkbuf = filebuf + file->size + 4;
grub_file_read(file, bkbuf, file->size);
oldpos = ctx->pos;
/* title --> menuentry */
grub_memcpy(filebuf, bkbuf, file->size);
tag = ventoy_systemd_conf_tag(filebuf, "title", 0);
vtoy_check_goto_out(tag);
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "menuentry \"%s\" {\n", tag);
/* linux xxx */
grub_memcpy(filebuf, bkbuf, file->size);
tag = ventoy_systemd_conf_tag(filebuf, "linux", 0);
if (!tag)
{
ctx->pos = oldpos;
goto out;
}
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, " echo \"Downloading kernel ...\"\n linux %s ", tag);
/* kernel options */
grub_memcpy(filebuf, bkbuf, file->size);
tag = ventoy_systemd_conf_tag(filebuf, "options", 0);
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "%s \n", tag ? tag : "");
/* initrd xxx xxx xxx */
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, " echo \"Downloading initrd ...\"\n initrd ");
grub_memcpy(filebuf, bkbuf, file->size);
tag = ventoy_systemd_conf_tag(filebuf, "initrd", 1);
while (tag)
{
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "%s ", tag);
tag = ventoy_systemd_conf_tag(tag + grub_strlen(tag) + 1, "initrd", 1);
}
vtoy_len_ssprintf(ctx->buf, ctx->pos, ctx->len, "\n boot\n}\n");
out:
grub_check_free(filebuf);
grub_file_close(file);
return 0;
}
grub_err_t ventoy_cmd_linux_systemd_menu(grub_extcmd_context_t ctxt, int argc, char **args)
{
static char *buf = NULL;
grub_fs_t fs;
char *device_name = NULL;
grub_device_t dev = NULL;
systemd_menu_ctx ctx;
(void)ctxt;
(void)argc;
if (!buf)
{
buf = grub_malloc(VTOY_LINUX_SYSTEMD_MENU_MAX_BUF);
if (!buf)
{
goto end;
}
}
device_name = grub_file_get_device_name(args[0]);
if (!device_name)
{
debug("failed to get device name %s\n", args[0]);
goto end;
}
dev = grub_device_open(device_name);
if (!dev)
{
debug("failed to open device %s\n", device_name);
goto end;
}
fs = grub_fs_probe(dev);
if (!fs)
{
debug("failed to probe fs %d\n", grub_errno);
goto end;
}
ctx.dev = args[0];
ctx.buf = buf;
ctx.pos = 0;
ctx.len = VTOY_LINUX_SYSTEMD_MENU_MAX_BUF;
fs->fs_dir(dev, "/loader/entries", ventoy_systemd_conf_hook, &ctx);
ventoy_memfile_env_set(args[1], buf, (ulonglong)(ctx.pos));
end:
grub_check_free(device_name);
check_free(dev, grub_device_close);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static int ventoy_limine_path_convert(char *path)
{
char newpath[256] = {0};
if (grub_strncmp(path, "boot://2/", 9) == 0)
{
grub_snprintf(newpath, sizeof(newpath), "(vtimghd,2)/%s", path + 9);
}
else if (grub_strncmp(path, "boot://1/", 9) == 0)
{
grub_snprintf(newpath, sizeof(newpath), "(vtimghd,1)/%s", path + 9);
}
if (newpath[0])
{
grub_snprintf(path, 1024, "%s", newpath);
}
return 0;
}
grub_err_t ventoy_cmd_linux_limine_menu(grub_extcmd_context_t ctxt, int argc, char **args)
{
int pos = 0;
int sub = 0;
int len = VTOY_LINUX_SYSTEMD_MENU_MAX_BUF;
char *filebuf = NULL;
char *start = NULL;
char *nextline = NULL;
grub_file_t file = NULL;
char *title = NULL;
char *kernel = NULL;
char *initrd = NULL;
char *param = NULL;
static char *buf = NULL;
(void)ctxt;
(void)argc;
if (!buf)
{
buf = grub_malloc(len + 4 * 1024);
if (!buf)
{
goto end;
}
}
title = buf + len;
kernel = title + 1024;
initrd = kernel + 1024;
param = initrd + 1024;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, args[0]);
if (!file)
{
return 0;
}
filebuf = grub_zalloc(file->size + 8);
if (!filebuf)
{
goto end;
}
grub_file_read(file, filebuf, file->size);
grub_file_close(file);
title[0] = kernel[0] = initrd[0] = param[0] = 0;
for (start = filebuf; start; start = nextline)
{
nextline = ventoy_get_line(start);
VTOY_SKIP_SPACE(start);
if (start[0] == ':')
{
if (start[1] == ':')
{
grub_snprintf(title, 1024, "%s", start + 2);
}
else
{
if (sub)
{
vtoy_len_ssprintf(buf, pos, len, "}\n");
sub = 0;
}
if (nextline && nextline[0] == ':' && nextline[1] == ':')
{
vtoy_len_ssprintf(buf, pos, len, "submenu \"[+] %s\" {\n", start + 2);
sub = 1;
title[0] = 0;
}
else
{
grub_snprintf(title, 1024, "%s", start + 1);
}
}
}
else if (grub_strncmp(start, "KERNEL_PATH=", 12) == 0)
{
grub_snprintf(kernel, 1024, "%s", start + 12);
}
else if (grub_strncmp(start, "MODULE_PATH=", 12) == 0)
{
grub_snprintf(initrd, 1024, "%s", start + 12);
}
else if (grub_strncmp(start, "KERNEL_CMDLINE=", 15) == 0)
{
grub_snprintf(param, 1024, "%s", start + 15);
}
if (title[0] && kernel[0] && initrd[0] && param[0])
{
ventoy_limine_path_convert(kernel);
ventoy_limine_path_convert(initrd);
vtoy_len_ssprintf(buf, pos, len, "menuentry \"%s\" {\n", title);
vtoy_len_ssprintf(buf, pos, len, " echo \"Downloading kernel ...\"\n linux %s %s\n", kernel, param);
vtoy_len_ssprintf(buf, pos, len, " echo \"Downloading initrd ...\"\n initrd %s\n", initrd);
vtoy_len_ssprintf(buf, pos, len, "}\n");
title[0] = kernel[0] = initrd[0] = param[0] = 0;
}
}
if (sub)
{
vtoy_len_ssprintf(buf, pos, len, "}\n");
sub = 0;
}
ventoy_memfile_env_set(args[1], buf, (ulonglong)pos);
end:
grub_check_free(filebuf);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}

View File

@ -35,6 +35,7 @@
#include <grub/crypto.h> #include <grub/crypto.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/font.h> #include <grub/font.h>
#include <grub/video.h>
#include <grub/ventoy.h> #include <grub/ventoy.h>
#include "ventoy_def.h" #include "ventoy_def.h"
@ -56,12 +57,16 @@ static injection_config *g_injection_head = NULL;
static auto_memdisk *g_auto_memdisk_head = NULL; static auto_memdisk *g_auto_memdisk_head = NULL;
static image_list *g_image_list_head = NULL; static image_list *g_image_list_head = NULL;
static conf_replace *g_conf_replace_head = NULL; static conf_replace *g_conf_replace_head = NULL;
static VTOY_JSON *g_menu_lang_json = NULL;
static int g_theme_id = 0; static int g_theme_id = 0;
static int g_theme_res_fit = 0;
static int g_theme_num = 0; static int g_theme_num = 0;
static theme_list *g_theme_head = NULL; static theme_list *g_theme_head = NULL;
static int g_theme_random = vtoy_theme_random_boot_second; static int g_theme_random = vtoy_theme_random_boot_second;
static char g_theme_single_file[256]; static char g_theme_single_file[256];
static char g_cur_menu_language[32] = {0};
static char g_push_menu_language[32] = {0};
static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath) static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath)
{ {
@ -171,11 +176,11 @@ static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
grub_printf("file: %s\n", value); grub_printf("file: %s\n", value);
if (value[0] == '/') if (value[0] == '/')
{ {
exist = ventoy_is_file_exist("%s%s", isodisk, value); exist = ventoy_check_file_exist("%s%s", isodisk, value);
} }
else else
{ {
exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value); exist = ventoy_check_file_exist("%s/ventoy/%s", isodisk, value);
} }
if (exist == 0) if (exist == 0)
@ -195,11 +200,11 @@ static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
grub_printf("file: %s\n", value); grub_printf("file: %s\n", value);
if (value[0] == '/') if (value[0] == '/')
{ {
exist = ventoy_is_file_exist("%s%s", isodisk, value); exist = ventoy_check_file_exist("%s%s", isodisk, value);
} }
else else
{ {
exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value); exist = ventoy_check_file_exist("%s/ventoy/%s", isodisk, value);
} }
if (exist == 0) if (exist == 0)
@ -375,6 +380,18 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
if (g_theme_num > 0) if (g_theme_num > 0)
{ {
vtoy_json_get_int(json->pstChild, "default_file", &g_theme_id); vtoy_json_get_int(json->pstChild, "default_file", &g_theme_id);
if (g_theme_id == 0)
{
vtoy_json_get_int(json->pstChild, "resolution_fit", &g_theme_res_fit);
if (g_theme_res_fit != 1)
{
g_theme_res_fit = 0;
}
grub_snprintf(val, sizeof(val), "%d", g_theme_res_fit);
ventoy_env_export("vtoy_res_fit", val);
}
if (g_theme_id > g_theme_num || g_theme_id < 0) if (g_theme_id > g_theme_num || g_theme_id < 0)
{ {
g_theme_id = 0; g_theme_id = 0;
@ -405,19 +422,19 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
if (value) if (value)
{ {
ventoy_env_export("VTLE_LFT", value); ventoy_env_export(ventoy_left_key, value);
} }
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top"); value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
if (value) if (value)
{ {
ventoy_env_export("VTLE_TOP", value); ventoy_env_export(ventoy_top_key, value);
} }
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color"); value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
if (value) if (value)
{ {
ventoy_env_export("VTLE_CLR", value); ventoy_env_export(ventoy_color_key, value);
} }
node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts"); node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts");
@ -463,7 +480,7 @@ static int ventoy_plugin_check_path(const char *path, const char *file)
return 1; return 1;
} }
if (!ventoy_is_file_exist("%s%s", path, file)) if (!ventoy_check_file_exist("%s%s", path, file))
{ {
grub_printf("%s%s does NOT exist\n", path, file); grub_printf("%s%s does NOT exist\n", path, file);
return 1; return 1;
@ -561,7 +578,7 @@ static int ventoy_plugin_parse_fullpath
{ {
debug("%s is string type data\n", node->pcName); debug("%s is string type data\n", node->pcName);
if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal))) if ((node->unData.pcStrVal[0] != '/') || (!ventoy_check_file_exist("%s%s", isodisk, node->unData.pcStrVal)))
{ {
debug("%s%s file not found\n", isodisk, node->unData.pcStrVal); debug("%s%s file not found\n", isodisk, node->unData.pcStrVal);
return 1; return 1;
@ -596,7 +613,7 @@ static int ventoy_plugin_parse_fullpath
for (count = 0, child = node->pstChild; child; child = child->pstNext) for (count = 0, child = node->pstChild; child; child = child->pstNext)
{ {
if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal)) if (ventoy_check_file_exist("%s%s", isodisk, child->unData.pcStrVal))
{ {
grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal); grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal);
path++; path++;
@ -960,7 +977,7 @@ static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd)
return 1; return 1;
} }
if (len - 1 - (int)(long)(pos - pwdstr) != 32) if (len - 1 - ((long)pos - (long)pwdstr) != 32)
{ {
if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr); if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr);
return 1; return 1;
@ -1401,7 +1418,7 @@ static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
{ {
grub_printf("image: <%s> [ * ]\n", path); grub_printf("image: <%s> [ * ]\n", path);
} }
else if (ventoy_is_file_exist("%s%s", isodisk, path)) else if (ventoy_check_file_exist("%s%s", isodisk, path))
{ {
grub_printf("image: <%s> [ OK ]\n", path); grub_printf("image: <%s> [ OK ]\n", path);
} }
@ -1542,7 +1559,7 @@ static int ventoy_plugin_menutip_check(VTOY_JSON *json, const char *isodisk)
{ {
grub_printf("image: <%s> [ * ]\n", path); grub_printf("image: <%s> [ * ]\n", path);
} }
else if (ventoy_is_file_exist("%s%s", isodisk, path)) else if (ventoy_check_file_exist("%s%s", isodisk, path))
{ {
grub_printf("image: <%s> [ OK ]\n", path); grub_printf("image: <%s> [ OK ]\n", path);
} }
@ -2641,10 +2658,15 @@ install_template * ventoy_plugin_find_install_template(const char *isopath)
return NULL; return NULL;
} }
char * ventoy_plugin_get_cur_install_template(const char *isopath) char * ventoy_plugin_get_cur_install_template(const char *isopath, install_template **cur)
{ {
install_template *node = NULL; install_template *node = NULL;
if (cur)
{
*cur = NULL;
}
node = ventoy_plugin_find_install_template(isopath); node = ventoy_plugin_find_install_template(isopath);
if ((!node) || (!node->templatepath)) if ((!node) || (!node->templatepath))
{ {
@ -2656,6 +2678,11 @@ char * ventoy_plugin_get_cur_install_template(const char *isopath)
return NULL; return NULL;
} }
if (cur)
{
*cur = node;
}
return node->templatepath[node->cursel].path; return node->templatepath[node->cursel].path;
} }
@ -2684,6 +2711,8 @@ persistence_config * ventoy_plugin_find_persistent(const char *isopath)
int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list) int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
{ {
int rc = 1; int rc = 1;
int len = 0;
char *path = NULL;
grub_uint64_t start = 0; grub_uint64_t start = 0;
grub_file_t file = NULL; grub_file_t file = NULL;
persistence_config *node = NULL; persistence_config *node = NULL;
@ -2704,10 +2733,22 @@ int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, vento
return 1; return 1;
} }
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path); path = node->backendpath[index].path;
if (node->backendpath[index].vlnk_add == 0)
{
len = grub_strlen(path);
if (len > 9 && grub_strncmp(path + len - 9, ".vlnk.dat", 9) == 0)
{
ventoy_add_vlnk_file(NULL, path);
node->backendpath[index].vlnk_add = 1;
}
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, path);
if (!file) if (!file)
{ {
debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path); debug("Failed to open file %s%s\n", g_iso_disk_name, path);
goto end; goto end;
} }
@ -3030,14 +3071,15 @@ int ventoy_plugin_get_image_list_index(int type, const char *name)
return 0; return 0;
} }
conf_replace * ventoy_plugin_find_conf_replace(const char *iso) int ventoy_plugin_find_conf_replace(const char *iso, conf_replace *nodes[VTOY_MAX_CONF_REPLACE])
{ {
int n = 0;
int len; int len;
conf_replace *node; conf_replace *node;
if (!g_conf_replace_head) if (!g_conf_replace_head)
{ {
return NULL; return 0;
} }
len = (int)grub_strlen(iso); len = (int)grub_strlen(iso);
@ -3046,11 +3088,15 @@ conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
{ {
if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0) if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0)
{ {
return node; nodes[n++] = node;
if (n >= VTOY_MAX_CONF_REPLACE)
{
return n;
}
} }
} }
return NULL; return n;
} }
dud * ventoy_plugin_find_dud(const char *iso) dud * ventoy_plugin_find_dud(const char *iso)
@ -3340,7 +3386,7 @@ grub_err_t ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt, int argc, cha
} }
pos += grub_snprintf(buf + pos, bufsize - pos, pos += grub_snprintf(buf + pos, bufsize - pos,
"menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {\n" "menuentry \"$VTLANG_RETURN_PREVIOUS\" --class=vtoyret VTOY_RET {\n"
"echo 'Return ...'\n" "echo 'Return ...'\n"
"}\n"); "}\n");
@ -3350,12 +3396,18 @@ grub_err_t ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt, int argc, cha
return 0; return 0;
} }
extern char g_ventoy_theme_path[256];
grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_uint32_t i = 0; grub_uint32_t i = 0;
grub_uint32_t mod = 0; grub_uint32_t mod = 0;
grub_uint32_t theme_num = 0;
theme_list *node = g_theme_head; theme_list *node = g_theme_head;
struct grub_datetime datetime; struct grub_datetime datetime;
struct grub_video_mode_info info;
char buf[64];
char **pThemePath = NULL;
(void)argc; (void)argc;
(void)args; (void)args;
@ -3386,41 +3438,82 @@ grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **arg
goto end; goto end;
} }
pThemePath = (char **)grub_zalloc(sizeof(char *) * g_theme_num);
if (!pThemePath)
{
goto end;
}
if (g_theme_res_fit)
{
if (grub_video_get_info(&info) == GRUB_ERR_NONE)
{
debug("get video info success %ux%u\n", info.width, info.height);
grub_snprintf(buf, sizeof(buf), "%ux%u", info.width, info.height);
for (node = g_theme_head; node; node = node->next)
{
if (grub_strstr(node->theme.path, buf))
{
pThemePath[theme_num++] = node->theme.path;
}
}
}
}
if (theme_num == 0)
{
for (node = g_theme_head; node; node = node->next)
{
pThemePath[theme_num++] = node->theme.path;
}
}
if (theme_num == 1)
{
mod = 0;
debug("Only 1 theme match, no need to random.\n");
}
else
{
grub_memset(&datetime, 0, sizeof(datetime)); grub_memset(&datetime, 0, sizeof(datetime));
grub_get_datetime(&datetime); grub_get_datetime(&datetime);
if (g_theme_random == vtoy_theme_random_boot_second) if (g_theme_random == vtoy_theme_random_boot_second)
{ {
grub_divmod32((grub_uint32_t)datetime.second, (grub_uint32_t)g_theme_num, &mod); grub_divmod32((grub_uint32_t)datetime.second, theme_num, &mod);
} }
else if (g_theme_random == vtoy_theme_random_boot_day) else if (g_theme_random == vtoy_theme_random_boot_day)
{ {
grub_divmod32((grub_uint32_t)datetime.day, (grub_uint32_t)g_theme_num, &mod); grub_divmod32((grub_uint32_t)datetime.day, theme_num, &mod);
} }
else if (g_theme_random == vtoy_theme_random_boot_month) else if (g_theme_random == vtoy_theme_random_boot_month)
{ {
grub_divmod32((grub_uint32_t)datetime.month, (grub_uint32_t)g_theme_num, &mod); grub_divmod32((grub_uint32_t)datetime.month, theme_num, &mod);
} }
debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n", debug("%04d/%02d/%02d %02d:%02d:%02d theme_num:%d mod:%d\n",
datetime.year, datetime.month, datetime.day, datetime.year, datetime.month, datetime.day,
datetime.hour, datetime.minute, datetime.second, datetime.hour, datetime.minute, datetime.second,
g_theme_random, mod); theme_num, mod);
for (i = 0; i < mod && node; i++)
{
node = node->next;
} }
debug("random theme %s\n", node->theme.path); if (argc > 0 && grub_strcmp(args[0], "switch") == 0)
grub_env_set("theme", node->theme.path); {
grub_snprintf(g_ventoy_theme_path, sizeof(g_ventoy_theme_path), "%s", pThemePath[mod]);
}
else
{
debug("random theme %s\n", pThemePath[mod]);
grub_env_set("theme", pThemePath[mod]);
}
g_ventoy_menu_refresh = 1;
end: end:
grub_check_free(pThemePath);
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
extern char g_ventoy_theme_path[256];
grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
(void)argc; (void)argc;
@ -3438,3 +3531,127 @@ grub_err_t ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt, int argc, char
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
const char *ventoy_get_vmenu_title(const char *vMenu)
{
return vtoy_json_get_string_ex(g_menu_lang_json->pstChild, vMenu);
}
int ventoy_plugin_load_menu_lang(int init, const char *lang)
{
int ret = 1;
grub_file_t file = NULL;
char *buf = NULL;
if (grub_strcmp(lang, g_cur_menu_language) == 0)
{
debug("Same menu lang %s\n", lang);
return 0;
}
grub_snprintf(g_cur_menu_language, sizeof(g_cur_menu_language), "%s", lang);
debug("Load menu lang %s\n", g_cur_menu_language);
if (g_menu_lang_json)
{
vtoy_json_destroy(g_menu_lang_json);
g_menu_lang_json = NULL;
}
g_menu_lang_json = vtoy_json_create();
if (!g_menu_lang_json)
{
goto end;
}
file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(vt_menu_tarfs)/menu/%s.json", lang);
if (!file)
{
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);
vtoy_json_parse(g_menu_lang_json, buf);
if (g_default_menu_mode == 0)
{
grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_TREE"));
}
else
{
grub_snprintf(g_ventoy_hotkey_tip, sizeof(g_ventoy_hotkey_tip), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_LIST"));
}
if (init == 0)
{
ventoy_menu_push_key(GRUB_TERM_ESC);
ventoy_menu_push_key(GRUB_TERM_ESC);
g_ventoy_menu_refresh = 1;
}
ret = 0;
end:
check_free(file, grub_file_close);
grub_check_free(buf);
return ret;
}
grub_err_t ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
(void)argc;
if (argc > 0)
{
grub_env_set(args[0], g_cur_menu_language);
}
else
{
grub_printf("%s\n", g_cur_menu_language);
grub_printf("%s\n", g_ventoy_hotkey_tip);
grub_refresh();
}
VENTOY_CMD_RETURN(0);
}
grub_err_t ventoy_cmd_push_menulang(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)argc;
(void)ctxt;
if (g_push_menu_language[0] == 0)
{
grub_memcpy(g_push_menu_language, g_cur_menu_language, sizeof(g_push_menu_language));
ventoy_plugin_load_menu_lang(0, args[0]);
}
VENTOY_CMD_RETURN(0);
}
grub_err_t ventoy_cmd_pop_menulang(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)argc;
(void)ctxt;
(void)args;
if (g_push_menu_language[0])
{
ventoy_plugin_load_menu_lang(0, g_push_menu_language);
g_push_menu_language[0] = 0;
}
VENTOY_CMD_RETURN(0);
}

View File

@ -48,6 +48,7 @@ int g_mod_new_len = 0;
char *g_mod_new_data = NULL; char *g_mod_new_data = NULL;
int g_mod_search_magic = 0; int g_mod_search_magic = 0;
int g_unix_vlnk_boot = 0;
int g_ko_fillmap_len = 0; int g_ko_fillmap_len = 0;
char *g_ko_fillmap_data = NULL; char *g_ko_fillmap_data = NULL;
@ -273,13 +274,14 @@ static void ventoy_unix_fill_virt_data( grub_uint64_t isosize, ventoy_chain_h
return; return;
} }
static int ventoy_freebsd_append_conf(char *buf, const char *isopath) static int ventoy_freebsd_append_conf(char *buf, const char *isopath, const char *alias)
{ {
int pos = 0; int pos = 0;
grub_uint32_t i; grub_uint32_t i;
grub_disk_t disk; grub_disk_t disk;
grub_file_t isofile; grub_file_t isofile;
char uuid[64] = {0}; char uuid[64] = {0};
const char *val = NULL;
ventoy_img_chunk *chunk; ventoy_img_chunk *chunk;
grub_uint8_t disk_sig[4]; grub_uint8_t disk_sig[4];
grub_uint8_t disk_guid[16]; grub_uint8_t disk_guid[16];
@ -295,12 +297,30 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath)
vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES"); vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES");
vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path); vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path);
if (alias)
{
vtoy_ssprintf(buf, pos, "hint.ventoy.0.alias=\"%s\"\n", alias);
}
if (g_unix_vlnk_boot)
{
vtoy_ssprintf(buf, pos, "hint.ventoy.0.vlnk=%d\n", 1);
}
val = ventoy_get_env("VTOY_UNIX_REMOUNT");
if (val && val[0] == '1' && val[1] == 0)
{
vtoy_ssprintf(buf, pos, "hint.ventoy.0.remount=%d\n", 1);
}
if (g_mod_search_magic) if (g_mod_search_magic)
{ {
debug("hint.ventoy NO need\n"); debug("hint.ventoy NO need\n");
goto out; goto out;
} }
debug("Fill hint.ventoy info\n");
disk = isofile->device->disk; disk = isofile->device->disk;
ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig); ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig);
@ -349,6 +369,7 @@ grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **ar
(void)argc; (void)argc;
(void)args; (void)args;
g_unix_vlnk_boot = 0;
g_mod_search_magic = 0; g_mod_search_magic = 0;
g_conf_new_len = 0; g_conf_new_len = 0;
g_mod_new_len = 0; g_mod_new_len = 0;
@ -363,6 +384,27 @@ grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **ar
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
grub_err_t ventoy_cmd_unix_check_vlnk(grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_file_t file;
(void)ctxt;
if (argc != 1)
{
return 1;
}
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (file)
{
g_unix_vlnk_boot = file->vlnk;
grub_file_close(file);
}
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_file_t file; grub_file_t file;
@ -403,12 +445,16 @@ grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, ch
ver = vtoy_json_get_string_ex(json->pstChild, "Version"); ver = vtoy_json_get_string_ex(json->pstChild, "Version");
if (ver) if (ver)
{ {
debug("freenas version:<%s>\n", ver); debug("NAS version:<%s>\n", ver);
if (grub_strncmp(ver, "TrueNAS-", 8) == 0)
{
ver += 8;
}
ventoy_set_env(args[1], ver); ventoy_set_env(args[1], ver);
} }
else else
{ {
debug("freenas version:<%s>\n", "NOT FOUND"); debug("NAS version:<%s>\n", "NOT FOUND");
grub_env_unset(args[1]); grub_env_unset(args[1]);
} }
@ -647,6 +693,109 @@ out:
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
grub_err_t ventoy_cmd_unix_replace_grub_conf(grub_extcmd_context_t ctxt, int argc, char **args)
{
int len = 0;
grub_uint32_t i;
char *data;
char *pos;
const char *val = NULL;
grub_uint64_t offset;
grub_file_t file;
char extcfg[512];
const char *confile = NULL;
const char * loader_conf[] =
{
"/boot/grub/grub.cfg",
};
(void)ctxt;
if (argc != 1 && argc != 2)
{
debug("Replace conf invalid argc %d\n", argc);
return 1;
}
for (i = 0; i < sizeof(loader_conf) / sizeof(loader_conf[0]); i++)
{
if (ventoy_get_file_override(loader_conf[i], &offset) == 0)
{
confile = loader_conf[i];
g_conf_override_offset = offset;
break;
}
}
if (confile == NULL)
{
debug("Can't find grub.cfg file from %u locations\n", i);
return 1;
}
file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(loop)/%s", confile);
if (!file)
{
debug("Failed to open %s \n", confile);
return 1;
}
debug("old grub2 conf file size:%d\n", (int)file->size);
data = grub_malloc(VTOY_MAX_SCRIPT_BUF);
if (!data)
{
grub_file_close(file);
return 1;
}
grub_file_read(file, data, file->size);
grub_file_close(file);
g_conf_new_data = data;
g_conf_new_len = (int)file->size;
pos = grub_strstr(data, "kfreebsd /boot/kernel/kernel");
if (pos)
{
pos += grub_strlen("kfreebsd /boot/kernel/kernel");
if (grub_strncmp(pos, ".gz", 3) == 0)
{
pos += 3;
}
if (argc == 2)
{
vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s; set kFreeBSD.hint.ventoy.0.alias=\"%s\"", args[0], args[1]);
}
else
{
vtoy_ssprintf(extcfg, len, ";kfreebsd_module_elf %s", args[0]);
}
if (g_unix_vlnk_boot)
{
vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.vlnk=%d", 1);
}
val = ventoy_get_env("VTOY_UNIX_REMOUNT");
if (val && val[0] == '1' && val[1] == 0)
{
vtoy_ssprintf(extcfg, len, ";set kFreeBSD.hint.ventoy.0.remount=%d", 1);
}
grub_memmove(pos + len, pos, (int)(file->size - (pos - data)));
grub_memcpy(pos, extcfg, len);
g_conf_new_len += len;
}
else
{
debug("no kfreebsd found\n");
}
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_uint32_t i; grub_uint32_t i;
@ -662,7 +811,7 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch
(void)ctxt; (void)ctxt;
if (argc != 2) if (argc != 2 && argc != 3)
{ {
debug("Replace conf invalid argc %d\n", argc); debug("Replace conf invalid argc %d\n", argc);
return 1; return 1;
@ -691,7 +840,7 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch
return 1; return 1;
} }
debug("old conf file size:%d\n", (int)file->size); debug("old conf file <%s> size:%d\n", confile, (int)file->size);
data = grub_malloc(VTOY_MAX_SCRIPT_BUF); data = grub_malloc(VTOY_MAX_SCRIPT_BUF);
if (!data) if (!data)
@ -708,7 +857,7 @@ grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, ch
if (grub_strcmp(args[0], "FreeBSD") == 0) if (grub_strcmp(args[0], "FreeBSD") == 0)
{ {
g_conf_new_len += ventoy_freebsd_append_conf(data + file->size, args[1]); g_conf_new_len += ventoy_freebsd_append_conf(data + file->size, args[1], (argc > 2) ? args[2] : NULL);
} }
else if (grub_strcmp(args[0], "DragonFly") == 0) else if (grub_strcmp(args[0], "DragonFly") == 0)
{ {
@ -723,13 +872,13 @@ static int ventoy_unix_search_magic(char *data, int len)
int i; int i;
grub_uint32_t *magic = NULL; grub_uint32_t *magic = NULL;
for (i = 0; i < len; i += 65536) for (i = 0; i < len; i += 4096)
{ {
magic = (grub_uint32_t *)(data + i); magic = (grub_uint32_t *)(data + i);
if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 && if (magic[0] == VENTOY_UNIX_SEG_MAGIC0 && magic[1] == VENTOY_UNIX_SEG_MAGIC1 &&
magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3) magic[2] == VENTOY_UNIX_SEG_MAGIC2 && magic[3] == VENTOY_UNIX_SEG_MAGIC3)
{ {
debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 16)); debug("unix find search magic at 0x%x loop:%d\n", i, (i >> 12));
g_mod_search_magic = i; g_mod_search_magic = i;
return 0; return 0;
} }
@ -969,7 +1118,6 @@ grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char
const char *pLastChain = NULL; const char *pLastChain = NULL;
const char *compatible; const char *compatible;
ventoy_chain_head *chain; ventoy_chain_head *chain;
char envbuf[64];
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
@ -1040,18 +1188,15 @@ grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char
} }
} }
chain = grub_malloc(size); chain = ventoy_alloc_chain(size);
if (!chain) if (!chain)
{ {
grub_printf("Failed to alloc chain memory size %u\n", size); grub_printf("Failed to alloc chain unix memory size %u\n", size);
grub_file_close(file); grub_file_close(file);
return 1; return 1;
} }
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_env_set("vtoy_chain_mem_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_env_set("vtoy_chain_mem_size", envbuf);
grub_memset(chain, 0, sizeof(ventoy_chain_head)); grub_memset(chain, 0, sizeof(ventoy_chain_head));

View File

@ -148,9 +148,10 @@ static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy
return 0; return 0;
} }
static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, int *index) static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, int *index, grub_uint64_t *poffset)
{ {
int i; int i;
int find = 0;
int ret = 1; int ret = 1;
grub_uint64_t start; grub_uint64_t start;
grub_file_t file = NULL; grub_file_t file = NULL;
@ -183,6 +184,7 @@ static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, i
if (start == gpt->PartTbl[i].StartLBA) if (start == gpt->PartTbl[i].StartLBA)
{ {
*index = i; *index = i;
find = 1;
break; break;
} }
} }
@ -196,11 +198,22 @@ static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, i
if ((grub_uint32_t)start == gpt->MBR.PartTbl[i].StartSectorId) if ((grub_uint32_t)start == gpt->MBR.PartTbl[i].StartSectorId)
{ {
*index = i; *index = i;
find = 1;
break; break;
} }
} }
} }
if (find == 0) // MBR Logical partition
{
if (file->device->disk->partition->number > 0)
{
*index = file->device->disk->partition->number;
debug("Fall back part number: %d\n", *index);
}
}
*poffset = start;
ret = 0; ret = 0;
end: end:
@ -226,7 +239,7 @@ static int ventoy_vhd_patch_disk(const char *vhdpath, ventoy_patch_vhd *patch1,
else else
{ {
gpt = grub_zalloc(sizeof(ventoy_gpt_info)); gpt = grub_zalloc(sizeof(ventoy_gpt_info));
ventoy_vhd_read_parttbl(vhdpath, gpt, &partIndex); ventoy_vhd_read_parttbl(vhdpath, gpt, &partIndex, &offset);
debug("This is HDD partIndex %d %s\n", partIndex, vhdpath); debug("This is HDD partIndex %d %s\n", partIndex, vhdpath);
} }
@ -248,10 +261,12 @@ static int ventoy_vhd_patch_disk(const char *vhdpath, ventoy_patch_vhd *patch1,
patch1->part_type = patch2->part_type = 0; patch1->part_type = patch2->part_type = 0;
} }
else else
{
if (offset == 0)
{ {
offset = gpt->MBR.PartTbl[partIndex].StartSectorId; offset = gpt->MBR.PartTbl[partIndex].StartSectorId;
}
offset *= 512; offset *= 512;
debug("MBR disk signature: %02x%02x%02x%02x Part(%d) offset:%llu\n", debug("MBR disk signature: %02x%02x%02x%02x Part(%d) offset:%llu\n",
gpt->MBR.BootCode[0x1b8 + 0], gpt->MBR.BootCode[0x1b8 + 1], gpt->MBR.BootCode[0x1b8 + 0], gpt->MBR.BootCode[0x1b8 + 1],
gpt->MBR.BootCode[0x1b8 + 2], gpt->MBR.BootCode[0x1b8 + 3], gpt->MBR.BootCode[0x1b8 + 2], gpt->MBR.BootCode[0x1b8 + 3],
@ -305,7 +320,6 @@ grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char *
int patchoffset[2]; int patchoffset[2];
ventoy_patch_vhd *patch1; ventoy_patch_vhd *patch1;
ventoy_patch_vhd *patch2; ventoy_patch_vhd *patch2;
char envbuf[64];
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
@ -356,15 +370,9 @@ grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char *
/* set buffer and size */ /* set buffer and size */
#ifdef GRUB_MACHINE_EFI #ifdef GRUB_MACHINE_EFI
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_totbuf); ventoy_memfile_env_set("vtoy_vhd_buf", g_vhdboot_totbuf, (ulonglong)(g_vhdboot_isolen + sizeof(ventoy_chain_head)));
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", (int)(g_vhdboot_isolen + sizeof(ventoy_chain_head)));
grub_env_set("vtoy_vhd_buf_size", envbuf);
#else #else
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_isobuf); ventoy_memfile_env_set("vtoy_vhd_buf", g_vhdboot_isobuf, (ulonglong)g_vhdboot_isolen);
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", g_vhdboot_isolen);
grub_env_set("vtoy_vhd_buf_size", envbuf);
#endif #endif
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
@ -496,7 +504,7 @@ grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char *
vhd_footer_t vhdfoot; vhd_footer_t vhdfoot;
VDIPREHEADER vdihdr; VDIPREHEADER vdihdr;
char type[16] = {0}; char type[16] = {0};
ventoy_gpt_info *gpt; ventoy_gpt_info *gpt = NULL;
(void)ctxt; (void)ctxt;
@ -645,7 +653,6 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
grub_disk_t disk; grub_disk_t disk;
const char *pLastChain = NULL; const char *pLastChain = NULL;
ventoy_chain_head *chain; ventoy_chain_head *chain;
char envbuf[64];
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
@ -667,6 +674,11 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
return 1; return 1;
} }
if (grub_strncmp(args[0], g_iso_path, grub_strlen(g_iso_path)))
{
file->vlnk = 1;
}
img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
size = sizeof(ventoy_chain_head) + img_chunk_size; size = sizeof(ventoy_chain_head) + img_chunk_size;
@ -682,18 +694,15 @@ grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char
} }
} }
chain = grub_malloc(size); chain = ventoy_alloc_chain(size);
if (!chain) if (!chain)
{ {
grub_printf("Failed to alloc chain memory size %u\n", size); grub_printf("Failed to alloc chain raw memory size %u\n", size);
grub_file_close(file); grub_file_close(file);
return 1; return 1;
} }
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_env_set("vtoy_chain_mem_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_env_set("vtoy_chain_mem_size", envbuf);
grub_env_export("vtoy_chain_mem_addr"); grub_env_export("vtoy_chain_mem_addr");
grub_env_export("vtoy_chain_mem_size"); grub_env_export("vtoy_chain_mem_size");

View File

@ -1015,7 +1015,7 @@ static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directo
return 0; return 0;
} }
static int ventoy_cat_exe_file_data(wim_tail *wim_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 windatalen)
{ {
int pe64 = 0; int pe64 = 0;
char file[256]; char file[256];
@ -1030,14 +1030,14 @@ static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, g
jump_align = ventoy_align(jump_len, 16); jump_align = ventoy_align(jump_len, 16);
wim_data->jump_exe_len = jump_len; 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_raw_len = jump_align + sizeof(ventoy_os_param) + windatalen + exe_len;
wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048); wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048);
wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len); wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len);
if (wim_data->jump_bin_data) if (wim_data->jump_bin_data)
{ {
grub_memcpy(wim_data->jump_bin_data, jump_data, jump_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); grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + windatalen, exe_data, exe_len);
} }
debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n", debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n",
@ -1046,26 +1046,74 @@ static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, g
return 0; return 0;
} }
int ventoy_fill_windows_rtdata(void *buf, char *isopath) static int ventoy_get_windows_rtdata_len(const char *iso, int *flag)
{ {
int size = 0;
int template_file_len = 0;
char *pos = NULL; char *pos = NULL;
char *script = NULL; char *script = NULL;
install_template *template_node = NULL;
*flag = 0;
size = (int)sizeof(ventoy_windows_data);
pos = grub_strstr(iso, "/");
if (!pos)
{
return size;
}
script = ventoy_plugin_get_cur_install_template(pos, &template_node);
if (script)
{
(*flag) |= WINDATA_FLAG_TEMPLATE;
template_file_len = template_node->filelen;
}
return size + template_file_len;
}
static int ventoy_fill_windows_rtdata(void *buf, char *isopath, int dataflag)
{
int template_len = 0;
char *pos = NULL;
char *end = NULL;
char *script = NULL;
const char *env = NULL; const char *env = NULL;
install_template *template_node = NULL;
ventoy_windows_data *data = (ventoy_windows_data *)buf; ventoy_windows_data *data = (ventoy_windows_data *)buf;
grub_memset(data, 0, sizeof(ventoy_windows_data)); grub_memset(data, 0, sizeof(ventoy_windows_data));
env = grub_env_get("VTOY_WIN11_BYPASS_CHECK");
if (env && env[0] == '1' && env[1] == 0)
{
data->windows11_bypass_check = 1;
}
env = grub_env_get("VTOY_WIN11_BYPASS_NRO");
if (env && env[0] == '1' && env[1] == 0)
{
data->windows11_bypass_nro = 1;
}
pos = grub_strstr(isopath, "/"); pos = grub_strstr(isopath, "/");
if (!pos) if (!pos)
{ {
return 1; return 1;
} }
script = ventoy_plugin_get_cur_install_template(pos); if (dataflag & WINDATA_FLAG_TEMPLATE)
{
script = ventoy_plugin_get_cur_install_template(pos, &template_node);
if (script) if (script)
{ {
debug("auto install script <%s>\n", script); data->auto_install_len = template_len = template_node->filelen;
grub_snprintf(data->auto_install_script, sizeof(data->auto_install_script) - 1, "%s", script); debug("auto install script OK <%s> <len:%d>\n", script, template_len);
end = ventoy_str_last(script, '/');
grub_snprintf(data->auto_install_script, sizeof(data->auto_install_script) - 1, "%s", end ? end + 1 : script);
grub_memcpy(data + 1, template_node->filebuf, template_len);
}
} }
else else
{ {
@ -1090,12 +1138,6 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath)
debug("injection archive not configed %s\n", pos); debug("injection archive not configed %s\n", pos);
} }
env = grub_env_get("VTOY_WIN11_BYPASS_CHECK");
if (env && env[0] == '1' && env[1] == 0)
{
data->windows11_bypass_check = 1;
}
return 0; return 0;
} }
@ -1125,7 +1167,7 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath)
if (wim_data->jump_bin_data) if (wim_data->jump_bin_data)
{ {
grub_memcpy(wim_data->jump_bin_data + jump_align, param, sizeof(ventoy_os_param)); 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); ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath, wim_data->windata_flag);
} }
grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len); grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len);
@ -1168,7 +1210,7 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath)
return 0; return 0;
} }
static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch, int windatalen)
{ {
int rc; int rc;
grub_uint16_t i; grub_uint16_t i;
@ -1285,7 +1327,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
if (0 == ventoy_read_resource(file, head, &(patch->replace_look->resource), (void **)&(exe_data))) if (0 == ventoy_read_resource(file, head, &(patch->replace_look->resource), (void **)&(exe_data)))
{ {
ventoy_cat_exe_file_data(wim_data, exe_len, exe_data); ventoy_cat_exe_file_data(wim_data, exe_len, exe_data, windatalen);
grub_free(exe_data); grub_free(exe_data);
} }
else else
@ -1328,17 +1370,128 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
return 0; return 0;
} }
grub_err_t ventoy_cmd_sel_winpe_wim(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
int pos = 0;
int len = 0;
int find = 0;
char *cmd = NULL;
wim_patch *node = NULL;
wim_patch *tmp = NULL;
grub_file_t file = NULL;
wim_header *head = NULL;
char cfgfile[128];
(void)ctxt;
(void)argc;
len = 8 * VTOY_SIZE_1KB;
cmd = (char *)grub_malloc(len + sizeof(wim_header));
if (!cmd)
{
return 1;
}
head = (wim_header *)(cmd + len);
grub_env_unset("vtoy_pe_wim_path");
for (node = g_wim_patch_head; node; node = node->next)
{
find = 0;
for (tmp = g_wim_patch_head; tmp != node; tmp = tmp->next)
{
if (tmp->valid && grub_strcasecmp(tmp->path, node->path) == 0)
{
find = 1;
break;
}
}
if (find)
{
continue;
}
g_ventoy_case_insensitive = 1;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->path);
g_ventoy_case_insensitive = 0;
if (!file)
{
debug("File %s%s NOT exist\n", args[0], node->path);
continue;
}
grub_file_read(file, head, sizeof(wim_header));
if (grub_memcmp(head->signature, WIM_HEAD_SIGNATURE, sizeof(head->signature)))
{
debug("Not a valid wim file %s\n", (char *)head->signature);
grub_file_close(file);
continue;
}
if (head->flags & FLAG_HEADER_COMPRESS_LZMS)
{
debug("LZMS compress is not supported 0x%x\n", head->flags);
grub_file_close(file);
continue;
}
grub_file_close(file);
node->valid = 1;
vtoy_len_ssprintf(cmd, pos, len, "menuentry \"%s\" --class=\"sel_wim\" {\n echo \"\"\n}\n", node->path);
}
if (pos > 0)
{
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
g_ventoy_suppress_esc_default = 0;
g_ventoy_secondary_menu_on = 1;
grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)cmd, pos);
grub_script_execute_sourcecode(cfgfile);
g_ventoy_menu_esc = 0;
g_ventoy_suppress_esc = 0;
g_ventoy_suppress_esc_default = 1;
g_ventoy_secondary_menu_on = 0;
for (node = g_wim_patch_head; node; node = node->next)
{
if (node->valid)
{
if (i == g_ventoy_last_entry)
{
grub_env_set("vtoy_pe_wim_path", node->path);
break;
}
i++;
}
}
}
grub_free(cmd);
return 0;
}
grub_err_t ventoy_cmd_locate_wim_patch(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)
{ {
int datalen = 0;
int dataflag = 0;
wim_patch *node = g_wim_patch_head; wim_patch *node = g_wim_patch_head;
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
(void)args; (void)args;
datalen = ventoy_get_windows_rtdata_len(args[1], &dataflag);
while (node) while (node)
{ {
if (0 == ventoy_wimdows_locate_wim(args[0], node)) node->wim_data.windata_flag = dataflag;
if (0 == ventoy_wimdows_locate_wim(args[0], node, datalen))
{ {
node->valid = 1; node->valid = 1;
g_wim_valid_patch_count++; g_wim_valid_patch_count++;
@ -1651,25 +1804,40 @@ static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chai
return; return;
} }
static int ventoy_windows_drive_map(ventoy_chain_head *chain) static int ventoy_windows_drive_map(ventoy_chain_head *chain, int vlnk)
{ {
int hd1 = 0;
grub_disk_t disk; grub_disk_t disk;
debug("drive map begin <%p> ...\n", chain); debug("drive map begin <%p> <%d> ...\n", chain, vlnk);
if (chain->disk_drive == 0x80)
{
disk = grub_disk_open("hd1"); disk = grub_disk_open("hd1");
if (disk) if (disk)
{ {
grub_disk_close(disk); grub_disk_close(disk);
debug("drive map needed %p\n", disk); hd1 = 1;
chain->drive_map = 0x81; debug("BIOS hd1 exist\n");
} }
else else
{ {
debug("failed to open disk %s\n", "hd1"); debug("failed to open disk %s\n", "hd1");
} }
if (vlnk)
{
if (g_ventoy_disk_bios_id == 0x80 && hd1)
{
debug("drive map needed vlnk %p\n", disk);
chain->drive_map = 0x81;
}
}
else if (chain->disk_drive == 0x80)
{
if (hd1)
{
debug("drive map needed normal %p\n", disk);
chain->drive_map = 0x81;
}
} }
else else
{ {
@ -1734,17 +1902,150 @@ end:
return rc; return rc;
} }
static int ventoy_extract_init_exe(char *wimfile, grub_uint8_t **pexe_data, grub_uint32_t *pexe_len, char *exe_name)
{
int rc;
int ret = 1;
grub_uint16_t i;
grub_file_t file = NULL;
grub_uint32_t exe_len = 0;
wim_header *head = NULL;
grub_uint16_t *uname = NULL;
grub_uint8_t *exe_data = NULL;
grub_uint8_t *decompress_data = NULL;
wim_lookup_entry *lookup = NULL;
wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL;
wim_directory_entry *search = NULL;
wim_stream_entry *stream = NULL;
wim_lookup_entry *replace_look = NULL;
wim_header wimhdr;
wim_hash hashdata;
head = &wimhdr;
file = grub_file_open(wimfile, VENTOY_FILE_TYPE);
if (!file)
{
goto out;
}
grub_file_read(file, head, sizeof(wim_header));
rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data);
if (rc)
{
grub_printf("failed to read meta data %d\n", rc);
goto out;
}
security = (wim_security_header *)decompress_data;
if (security->len > 0)
{
rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U));
}
else
{
rootdir = (wim_directory_entry *)(decompress_data + 8);
}
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
lookup = grub_malloc(head->lookup.raw_size);
grub_file_seek(file, head->lookup.offset);
grub_file_read(file, lookup, head->lookup.raw_size);
/* search winpeshl.exe dirent entry */
search = search_replace_wim_dirent(file, head, lookup, decompress_data, rootdir);
if (!search)
{
debug("Failed to find replace file %p\n", search);
goto out;
}
uname = (grub_uint16_t *)(search + 1);
for (i = 0; i < search->name_len / 2 && i < 200; i++)
{
exe_name[i] = (char)uname[i];
}
exe_name[i] = 0;
debug("find replace file at %p <%s>\n", search, exe_name);
grub_memset(&hashdata, 0, sizeof(wim_hash));
if (grub_memcmp(&hashdata, search->hash.sha1, sizeof(wim_hash)) == 0)
{
debug("search hash all 0, now do deep search\n");
stream = (wim_stream_entry *)((char *)search + search->len);
for (i = 0; i < search->streams; i++)
{
if (stream->name_len == 0)
{
grub_memcpy(&hashdata, stream->hash.sha1, sizeof(wim_hash));
debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n",
ventoy_varg_8(hashdata.sha1));
break;
}
stream = (wim_stream_entry *)((char *)stream + stream->len);
}
}
else
{
grub_memcpy(&hashdata, search->hash.sha1, sizeof(wim_hash));
}
/* find and extact winpeshl.exe */
replace_look = ventoy_find_look_entry(head, lookup, &hashdata);
if (replace_look)
{
exe_len = (grub_uint32_t)replace_look->resource.raw_size;
debug("find replace lookup entry_id:%ld raw_size:%u\n",
((long)replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len);
if (0 != ventoy_read_resource(file, head, &(replace_look->resource), (void **)&(exe_data)))
{
exe_len = 0;
exe_data = NULL;
debug("failed to read replace file meta data %u\n", exe_len);
}
}
else
{
debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n",
ventoy_varg_4(hashdata.sha1));
}
if (exe_data)
{
ret = 0;
*pexe_data = exe_data;
*pexe_len = exe_len;
}
out:
grub_check_free(lookup);
grub_check_free(decompress_data);
check_free(file, grub_file_close);
return ret;
}
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_uint32_t size = 0; int rc = 0;
int wim64 = 0;
int datalen = 0;
int dataflag = 0;
grub_uint32_t exe_len = 0;
grub_uint32_t jump_align = 0;
const char *addr = NULL; const char *addr = NULL;
ventoy_chain_head *chain = NULL; ventoy_chain_head *chain = NULL;
ventoy_os_param *param = NULL; grub_uint8_t *param = NULL;
char envbuf[64]; grub_uint8_t *exe_data = NULL;
ventoy_windows_data *rtdata = NULL;
char exename[128] = {0};
wim_tail wim_data;
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
(void)args;
addr = grub_env_get("vtoy_chain_mem_addr"); addr = grub_env_get("vtoy_chain_mem_addr");
if (!addr) if (!addr)
@ -1761,23 +2062,31 @@ grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc,
return 1; return 1;
} }
size = sizeof(ventoy_os_param) + sizeof(ventoy_windows_data); datalen = ventoy_get_windows_rtdata_len(chain->os_param.vtoy_img_path, &dataflag);
param = (ventoy_os_param *)grub_zalloc(size);
if (!param) rc = ventoy_extract_init_exe(args[0], &exe_data, &exe_len, exename);
if (rc)
{ {
return 1; return 1;
} }
wim64 = ventoy_is_pe64(exe_data);
grub_memcpy(param, &chain->os_param, sizeof(ventoy_os_param)); grub_memset(&wim_data, 0, sizeof(wim_data));
ventoy_fill_windows_rtdata(param + 1, param->vtoy_img_path); ventoy_cat_exe_file_data(&wim_data, exe_len, exe_data, datalen);
grub_check_free(exe_data);
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)param); jump_align = ventoy_align(wim_data.jump_exe_len, 16);
grub_env_set("vtoy_wimboot_mem_addr", envbuf); param = wim_data.jump_bin_data;
debug("vtoy_wimboot_mem_addr: %s\n", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size); grub_memcpy(param + jump_align, &chain->os_param, sizeof(ventoy_os_param));
grub_env_set("vtoy_wimboot_mem_size", envbuf);
debug("vtoy_wimboot_mem_size: %s\n", envbuf); rtdata = (ventoy_windows_data *)(param + jump_align + sizeof(ventoy_os_param));
ventoy_fill_windows_rtdata(rtdata, chain->os_param.vtoy_img_path, dataflag);
ventoy_memfile_env_set("vtoy_wimboot_mem", param, (ulonglong)(wim_data.bin_align_len));
grub_env_set(args[1], exename);
grub_env_set(args[2], wim64 ? "64" : "32");
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
@ -1797,7 +2106,6 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
const char *pLastChain = NULL; const char *pLastChain = NULL;
const char *compatible; const char *compatible;
ventoy_chain_head *chain; ventoy_chain_head *chain;
char envbuf[64];
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
@ -1819,8 +2127,11 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
if (0 == ventoy_compatible && g_wim_valid_patch_count == 0) if (0 == ventoy_compatible && g_wim_valid_patch_count == 0)
{ {
unknown_image = 1; unknown_image = 1;
if (!g_ventoy_wimboot_mode)
{
debug("Warning: %s was not recognized by Ventoy\n", args[0]); debug("Warning: %s was not recognized by Ventoy\n", args[0]);
} }
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
if (!file) if (!file)
@ -1881,18 +2192,15 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
} }
} }
chain = grub_malloc(size); chain = ventoy_alloc_chain(size);
if (!chain) if (!chain)
{ {
grub_printf("Failed to alloc chain memory size %u\n", size); grub_printf("Failed to alloc chain win1 memory size %u\n", size);
grub_file_close(file); grub_file_close(file);
return 1; return 1;
} }
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_env_set("vtoy_chain_mem_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_env_set("vtoy_chain_mem_size", envbuf);
grub_memset(chain, 0, sizeof(ventoy_chain_head)); grub_memset(chain, 0, sizeof(ventoy_chain_head));
@ -1961,7 +2269,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
if (ventoy_is_efi_os() == 0) if (ventoy_is_efi_os() == 0)
{ {
ventoy_windows_drive_map(chain); ventoy_windows_drive_map(chain, file->vlnk);
} }
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
@ -1994,21 +2302,12 @@ static grub_uint32_t ventoy_get_wim_iso_offset(const char *filepath)
return imgoffset; return imgoffset;
} }
static int ventoy_get_wim_chunklist(const char *filename, ventoy_img_chunk_list *wimchunk, grub_uint64_t *wimsize) static int ventoy_get_wim_chunklist(grub_file_t wimfile, ventoy_img_chunk_list *wimchunk)
{ {
grub_file_t wimfile;
wimfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", filename);
if (!wimfile)
{
return 1;
}
grub_memset(wimchunk, 0, sizeof(ventoy_img_chunk_list)); grub_memset(wimchunk, 0, sizeof(ventoy_img_chunk_list));
wimchunk->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); wimchunk->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
if (NULL == wimchunk->chunk) if (NULL == wimchunk->chunk)
{ {
grub_file_close(wimfile);
return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
} }
@ -2017,12 +2316,70 @@ static int ventoy_get_wim_chunklist(const char *filename, ventoy_img_chunk_list
ventoy_get_block_list(wimfile, wimchunk, wimfile->device->disk->partition->start); ventoy_get_block_list(wimfile, wimchunk, wimfile->device->disk->partition->start);
*wimsize = wimfile->size;
grub_file_close(wimfile);
return 0; return 0;
} }
grub_err_t ventoy_cmd_is_standard_winiso(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i;
int ret = 1;
char prefix[32] = {0};
const char *chkfile[] =
{
"boot/bcd", "boot/boot.sdi", NULL
};
(void)ctxt;
(void)argc;
if (ventoy_check_file_exist("%s/sources/boot.wim", args[0]))
{
prefix[0] = 0;
}
else if (ventoy_check_file_exist("%s/x86/sources/boot.wim", args[0]))
{
grub_snprintf(prefix, sizeof(prefix), "/x86");
}
else if (ventoy_check_file_exist("%s/x64/sources/boot.wim", args[0]))
{
grub_snprintf(prefix, sizeof(prefix), "/x64");
}
else
{
debug("No boot.wim found.\n");
goto out;
}
for (i = 0; chkfile[i]; i++)
{
if (!ventoy_check_file_exist("%s%s/%s", args[0], prefix, chkfile[i]))
{
debug("%s not found.\n", chkfile[i]);
goto out;
}
}
if ((!ventoy_check_file_exist("%s%s/sources/install.wim", args[0], prefix)) &&
(!ventoy_check_file_exist("%s%s/sources/install.esd", args[0], prefix)))
{
debug("No install.wim(esd) found.\n");
goto out;
}
if (!ventoy_check_file_exist("%s/setup.exe", args[0]))
{
debug("No setup.exe found.\n");
goto out;
}
ret = 0;
debug("This is standard Windows ISO.\n");
out:
return ret;
}
grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_uint32_t boot_index; grub_uint32_t boot_index;
@ -2058,7 +2415,7 @@ grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, c
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_vlnk_wim_chain_data(grub_file_t wimfile)
{ {
grub_uint32_t i = 0; grub_uint32_t i = 0;
grub_uint32_t imgoffset = 0; grub_uint32_t imgoffset = 0;
@ -2077,12 +2434,8 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
ventoy_img_chunk *chunknode; ventoy_img_chunk *chunknode;
ventoy_override_chunk *override; ventoy_override_chunk *override;
ventoy_img_chunk_list wimchunk; ventoy_img_chunk_list wimchunk;
char envbuf[128];
(void)ctxt; debug("vlnk wim chain data begin <%s> ...\n", wimfile->name);
(void)argc;
debug("wim chain data begin <%s> ...\n", args[0]);
if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path) if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path)
{ {
@ -2097,11 +2450,173 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
return 1; return 1;
} }
if (0 != ventoy_get_wim_chunklist(args[0], &wimchunk, &wimsize)) if (0 != ventoy_get_wim_chunklist(wimfile, &wimchunk))
{ {
grub_printf("Failed to get wim chunklist\n"); grub_printf("Failed to get wim chunklist\n");
return 1; return 1;
} }
wimsize = wimfile->size;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path);
if (!file)
{
return 1;
}
boot_catlog = ventoy_get_iso_boot_catlog(file);
img_chunk1_size = g_wimiso_chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
img_chunk2_size = wimchunk.cur_chunk * sizeof(ventoy_img_chunk);
override_size = sizeof(ventoy_override_chunk) + g_wimiso_size;
size = sizeof(ventoy_chain_head) + img_chunk1_size + img_chunk2_size + override_size;
pLastChain = grub_env_get("vtoy_chain_mem_addr");
if (pLastChain)
{
chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16);
if (chain)
{
debug("free last chain memory %p\n", chain);
grub_free(chain);
}
}
chain = ventoy_alloc_chain(size);
if (!chain)
{
grub_printf("Failed to alloc chain win2 memory size %u\n", size);
grub_file_close(file);
return 1;
}
ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_memset(chain, 0, sizeof(ventoy_chain_head));
/* part 1: os parameter */
g_ventoy_chain_type = ventoy_chain_wim;
ventoy_fill_os_param(wimfile, &(chain->os_param));
/* part 2: chain head */
disk = wimfile->device->disk;
chain->disk_drive = disk->id;
chain->disk_sector_size = (1 << disk->log_sector_size);
chain->real_img_size_in_bytes = ventoy_align_2k(file->size) + ventoy_align_2k(wimsize);
chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes;
chain->boot_catalog = boot_catlog;
if (!ventoy_is_efi_os())
{
grub_file_seek(file, boot_catlog * 2048);
grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector));
}
/* part 3: image chunk */
chain->img_chunk_offset = sizeof(ventoy_chain_head);
chain->img_chunk_num = g_wimiso_chunk_list.cur_chunk + wimchunk.cur_chunk;
grub_memcpy((char *)chain + chain->img_chunk_offset, g_wimiso_chunk_list.chunk, img_chunk1_size);
chunknode = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
for (i = 0; i < g_wimiso_chunk_list.cur_chunk; i++)
{
chunknode->disk_end_sector = chunknode->disk_end_sector - chunknode->disk_start_sector;
chunknode->disk_start_sector = 0;
chunknode++;
}
/* fs cluster size >= 2048, so don't need to proc align */
/* align by 2048 */
chunknode = wimchunk.chunk + wimchunk.cur_chunk - 1;
i = (chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) % 4;
if (i)
{
chunknode->disk_end_sector += 4 - i;
}
isosector = (grub_uint32_t)((file->size + 2047) / 2048);
for (i = 0; i < wimchunk.cur_chunk; i++)
{
chunknode = wimchunk.chunk + i;
chunknode->img_start_sector = isosector;
chunknode->img_end_sector = chunknode->img_start_sector +
((chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) / 4) - 1;
isosector = chunknode->img_end_sector + 1;
}
grub_memcpy((char *)chain + chain->img_chunk_offset + img_chunk1_size, wimchunk.chunk, img_chunk2_size);
/* part 4: override chunk */
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk1_size + img_chunk2_size;
chain->override_chunk_num = 1;
override = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset);
override->img_offset = 0;
override->override_size = g_wimiso_size;
grub_file_seek(file, 0);
grub_file_read(file, override->override_data, file->size);
dirent = (ventoy_iso9660_override *)(override->override_data + imgoffset);
dirent->first_sector = (grub_uint32_t)((file->size + 2047) / 2048);
dirent->size = (grub_uint32_t)(wimsize);
dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
dirent->size_be = grub_swap_bytes32(dirent->size);
debug("imgoffset=%u first_sector=0x%x size=0x%x\n", imgoffset, dirent->first_sector, dirent->size);
if (ventoy_is_efi_os() == 0)
{
ventoy_windows_drive_map(chain, 0);
}
grub_file_close(file);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static grub_err_t ventoy_normal_wim_chain_data(grub_file_t wimfile)
{
grub_uint32_t i = 0;
grub_uint32_t imgoffset = 0;
grub_uint32_t size = 0;
grub_uint32_t isosector = 0;
grub_uint64_t wimsize = 0;
grub_uint32_t boot_catlog = 0;
grub_uint32_t img_chunk1_size = 0;
grub_uint32_t img_chunk2_size = 0;
grub_uint32_t override_size = 0;
grub_file_t file;
grub_disk_t disk;
const char *pLastChain = NULL;
ventoy_chain_head *chain;
ventoy_iso9660_override *dirent;
ventoy_img_chunk *chunknode;
ventoy_override_chunk *override;
ventoy_img_chunk_list wimchunk;
debug("normal wim chain data begin <%s> ...\n", wimfile->name);
if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path)
{
grub_printf("ventoy not ready\n");
return 1;
}
imgoffset = ventoy_get_wim_iso_offset(g_wimiso_path);
if (imgoffset == 0)
{
grub_printf("image offset not found\n");
return 1;
}
if (0 != ventoy_get_wim_chunklist(wimfile, &wimchunk))
{
grub_printf("Failed to get wim chunklist\n");
return 1;
}
wimsize = wimfile->size;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path); file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path);
if (!file) if (!file)
@ -2128,18 +2643,15 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
} }
} }
chain = grub_malloc(size); chain = ventoy_alloc_chain(size);
if (!chain) if (!chain)
{ {
grub_printf("Failed to alloc chain memory size %u\n", size); grub_printf("Failed to alloc chain win3 memory size %u\n", size);
grub_file_close(file); grub_file_close(file);
return 1; return 1;
} }
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); ventoy_memfile_env_set("vtoy_chain_mem", chain, (ulonglong)size);
grub_env_set("vtoy_chain_mem_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_env_set("vtoy_chain_mem_size", envbuf);
grub_memset(chain, 0, sizeof(ventoy_chain_head)); grub_memset(chain, 0, sizeof(ventoy_chain_head));
@ -2206,7 +2718,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
if (ventoy_is_efi_os() == 0) if (ventoy_is_efi_os() == 0)
{ {
ventoy_windows_drive_map(chain); ventoy_windows_drive_map(chain, 0);
} }
grub_file_close(file); grub_file_close(file);
@ -2214,6 +2726,33 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_err_t ret;
grub_file_t wimfile;
(void)ctxt;
(void)argc;
wimfile = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (!wimfile)
{
return 1;
}
if (wimfile->vlnk)
{
ret = ventoy_vlnk_wim_chain_data(wimfile);
}
else
{
ret = ventoy_normal_wim_chain_data(wimfile);
}
grub_file_close(wimfile);
return ret;
}
int ventoy_chain_file_size(const char *path) int ventoy_chain_file_size(const char *path)
{ {
int size; int size;

View File

@ -0,0 +1,329 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_CHARSET_HEADER
#define GRUB_CHARSET_HEADER 1
#include <grub/types.h>
#define GRUB_UINT8_1_LEADINGBIT 0x80
#define GRUB_UINT8_2_LEADINGBITS 0xc0
#define GRUB_UINT8_3_LEADINGBITS 0xe0
#define GRUB_UINT8_4_LEADINGBITS 0xf0
#define GRUB_UINT8_5_LEADINGBITS 0xf8
#define GRUB_UINT8_6_LEADINGBITS 0xfc
#define GRUB_UINT8_7_LEADINGBITS 0xfe
#define GRUB_UINT8_1_TRAILINGBIT 0x01
#define GRUB_UINT8_2_TRAILINGBITS 0x03
#define GRUB_UINT8_3_TRAILINGBITS 0x07
#define GRUB_UINT8_4_TRAILINGBITS 0x0f
#define GRUB_UINT8_5_TRAILINGBITS 0x1f
#define GRUB_UINT8_6_TRAILINGBITS 0x3f
#define GRUB_MAX_UTF8_PER_UTF16 4
/* You need at least one UTF-8 byte to have one UTF-16 word.
You need at least three UTF-8 bytes to have 2 UTF-16 words (surrogate pairs).
*/
#define GRUB_MAX_UTF16_PER_UTF8 1
#define GRUB_MAX_UTF8_PER_CODEPOINT 4
#define GRUB_UCS2_LIMIT 0x10000
#define GRUB_UTF16_UPPER_SURROGATE(code) \
(0xD800 | ((((code) - GRUB_UCS2_LIMIT) >> 10) & 0x3ff))
#define GRUB_UTF16_LOWER_SURROGATE(code) \
(0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff))
/* Process one character from UTF8 sequence.
At beginning set *code = 0, *count = 0. Returns 0 on failure and
1 on success. *count holds the number of trailing bytes. */
static inline int
grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count)
{
if (*count)
{
if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
{
*count = 0;
/* invalid */
return 0;
}
else
{
*code <<= 6;
*code |= (c & GRUB_UINT8_6_TRAILINGBITS);
(*count)--;
/* Overlong. */
if ((*count == 1 && *code <= 0x1f)
|| (*count == 2 && *code <= 0xf))
{
*code = 0;
*count = 0;
return 0;
}
return 1;
}
}
if ((c & GRUB_UINT8_1_LEADINGBIT) == 0)
{
*code = c;
return 1;
}
if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS)
{
*count = 1;
*code = c & GRUB_UINT8_5_TRAILINGBITS;
/* Overlong */
if (*code <= 1)
{
*count = 0;
*code = 0;
return 0;
}
return 1;
}
if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS)
{
*count = 2;
*code = c & GRUB_UINT8_4_TRAILINGBITS;
return 1;
}
if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS)
{
*count = 3;
*code = c & GRUB_UINT8_3_TRAILINGBITS;
return 1;
}
return 0;
}
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
static inline grub_size_t
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
{
grub_uint16_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
if (srcend)
*srcend = src;
while (srcsize && destsize)
{
int was_count = count;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (!grub_utf8_process (*src++, &code, &count))
{
code = '?';
count = 0;
/* Character c may be valid, don't eat it. */
if (was_count)
src--;
}
if (count != 0)
continue;
if (code == 0)
break;
if (destsize < 2 && code >= GRUB_UCS2_LIMIT)
break;
if (code >= GRUB_UCS2_LIMIT)
{
*p++ = GRUB_UTF16_UPPER_SURROGATE (code);
*p++ = GRUB_UTF16_LOWER_SURROGATE (code);
destsize -= 2;
}
else
{
*p++ = code;
destsize--;
}
}
if (srcend)
*srcend = src;
return p - dest;
}
/* Determine the last position where the UTF-8 string [beg, end) can
be safely cut. */
static inline grub_size_t
grub_getend (const char *beg, const char *end)
{
const char *ptr;
for (ptr = end - 1; ptr >= beg; ptr--)
if ((*ptr & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
break;
if (ptr < beg)
return 0;
if ((*ptr & GRUB_UINT8_1_LEADINGBIT) == 0)
return ptr + 1 - beg;
if ((*ptr & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS
&& ptr + 2 <= end)
return ptr + 2 - beg;
if ((*ptr & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS
&& ptr + 3 <= end)
return ptr + 3 - beg;
if ((*ptr & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS
&& ptr + 4 <= end)
return ptr + 4 - beg;
/* Invalid character or incomplete. Cut before it. */
return ptr - beg;
}
/* Convert UTF-16 to UTF-8. */
static inline grub_uint8_t *
grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src,
grub_size_t size)
{
grub_uint32_t code_high = 0;
while (size--)
{
grub_uint32_t code = *src++;
if (code_high)
{
if (code >= 0xDC00 && code <= 0xDFFF)
{
/* Surrogate pair. */
code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000;
*dest++ = (code >> 18) | 0xF0;
*dest++ = ((code >> 12) & 0x3F) | 0x80;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
else
{
/* Error... */
*dest++ = '?';
/* *src may be valid. Don't eat it. */
src--;
}
code_high = 0;
}
else
{
if (code <= 0x007F)
*dest++ = code;
else if (code <= 0x07FF)
{
*dest++ = (code >> 6) | 0xC0;
*dest++ = (code & 0x3F) | 0x80;
}
else if (code >= 0xD800 && code <= 0xDBFF)
{
code_high = code;
continue;
}
else if (code >= 0xDC00 && code <= 0xDFFF)
{
/* Error... */
*dest++ = '?';
}
else if (code < 0x10000)
{
*dest++ = (code >> 12) | 0xE0;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
else
{
*dest++ = (code >> 18) | 0xF0;
*dest++ = ((code >> 12) & 0x3F) | 0x80;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
}
}
return dest;
}
#define GRUB_MAX_UTF8_PER_LATIN1 2
/* Convert Latin1 to UTF-8. */
static inline grub_uint8_t *
grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src,
grub_size_t size)
{
while (size--)
{
if (!(*src & 0x80))
*dest++ = *src;
else
{
*dest++ = (*src >> 6) | 0xC0;
*dest++ = (*src & 0x3F) | 0x80;
}
src++;
}
return dest;
}
/* Convert UCS-4 to UTF-8. */
char *grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size);
int
grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
grub_ssize_t grub_utf8_to_ucs4_alloc (const char *msg,
grub_uint32_t **unicode_msg,
grub_uint32_t **last_position);
/* Returns the number of bytes the string src would occupy is converted
to UTF-8, excluding \0. */
grub_size_t
grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size);
/* Converts UCS-4 to UTF-8. Returns the number of bytes effectively written
excluding the trailing \0. */
grub_size_t
grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size,
grub_uint8_t *dest, grub_size_t destsize);
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend);
/* Returns -2 if not enough space, -1 on invalid character. */
grub_ssize_t
grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend,
grub_uint32_t code);
const grub_uint32_t *
grub_unicode_get_comb_start (const grub_uint32_t *str,
const grub_uint32_t *cur);
int
grub_utf8_get_num_code (const char *src, grub_size_t srcsize);
const char *
grub_utf8_offset_code (const char *src, grub_size_t srcsize, int num);
#endif

View File

@ -314,6 +314,11 @@
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
} }
#define GRUB_EFI_SMBIOS3_TABLE_GUID \
{ 0xf2fd1544, 0x9794, 0x4a2c, \
{ 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \
}
#define GRUB_EFI_SAL_TABLE_GUID \ #define GRUB_EFI_SAL_TABLE_GUID \
{ 0xeb9d2d32, 0x2d88, 0x11d3, \ { 0xeb9d2d32, 0x2d88, 0x11d3, \
{ 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \

View File

@ -88,7 +88,7 @@ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size); void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size);
void * EXPORT_FUNC (grub_efi_allocate_chain_buf) (grub_uint64_t size); void * EXPORT_FUNC (grub_efi_allocate_chain_buf) (grub_uint64_t size);
void EXPORT_FUNC (grub_efi_get_reserved_page_num) (grub_uint64_t *total, grub_uint64_t *org_required, grub_uint64_t *new_required);
extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
char **device, char **device,

View File

@ -0,0 +1,73 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2006,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/>.
*/
#ifndef GRUB_ENV_HEADER
#define GRUB_ENV_HEADER 1
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
#include <grub/menu.h>
struct grub_env_var;
typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var,
const char *val);
typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
const char *val);
struct grub_env_var
{
char *name;
char *value;
grub_env_read_hook_t read_hook;
grub_env_write_hook_t write_hook;
struct grub_env_var *next;
struct grub_env_var **prevp;
struct grub_env_var *sorted_next;
int global;
};
grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val);
const char *EXPORT_FUNC(grub_env_get) (const char *name);
void EXPORT_FUNC(grub_env_unset) (const char *name);
struct grub_env_var *EXPORT_FUNC(grub_env_update_get_sorted) (void);
#define FOR_SORTED_ENV(var) for (var = grub_env_update_get_sorted (); var; var = var->sorted_next)
grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
grub_env_read_hook_t read_hook,
grub_env_write_hook_t write_hook);
grub_err_t EXPORT_FUNC(grub_register_vtoy_menu_lang_hook) (grub_env_read_hook_t read_hook);
grub_err_t grub_env_context_open (void);
grub_err_t grub_env_context_close (void);
grub_err_t EXPORT_FUNC(grub_env_export) (const char *name);
void grub_env_unset_menu (void);
grub_menu_t grub_env_get_menu (void);
void grub_env_set_menu (grub_menu_t nmenu);
grub_err_t
grub_env_extractor_open (int source);
grub_err_t
grub_env_extractor_close (int source);
#endif /* ! GRUB_ENV_HEADER */

View File

@ -132,7 +132,8 @@ enum grub_file_type
/* --skip-sig is specified. */ /* --skip-sig is specified. */
GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000, GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000,
GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000 GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000,
GRUB_FILE_TYPE_NO_VLNK = 0x40000,
}; };
/* File description. */ /* File description. */
@ -141,6 +142,8 @@ struct grub_file
/* File name. */ /* File name. */
char *name; char *name;
int vlnk;
/* The underlying device. */ /* The underlying device. */
grub_device_t device; grub_device_t device;
@ -213,6 +216,11 @@ grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset); 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); grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
int EXPORT_FUNC(grub_file_is_vlnk_suffix)(const char *name, int len);
int EXPORT_FUNC(grub_file_add_vlnk)(const char *src, const char *dst);
int EXPORT_FUNC(grub_file_vtoy_vlnk)(const char *src, const char *dst);
const char * EXPORT_FUNC(grub_file_get_vlnk)(const char *name, int *vlnk);
/* Return value of grub_file_size() in case file size is unknown. */ /* Return value of grub_file_size() in case file size is unknown. */
#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL #define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL

View File

@ -128,5 +128,6 @@ grub_fs_unregister (grub_fs_t fs)
#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) #define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list))
grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
grub_fs_t EXPORT_FUNC(grub_fs_list_probe) (grub_device_t device, const char **list);
#endif /* ! GRUB_FS_HEADER */ #endif /* ! GRUB_FS_HEADER */

View File

@ -0,0 +1,128 @@
/* gfxmenu_view.h - gfxmenu view interface. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_GFXMENU_VIEW_HEADER
#define GRUB_GFXMENU_VIEW_HEADER 1
#include <grub/types.h>
#include <grub/err.h>
#include <grub/menu.h>
#include <grub/font.h>
#include <grub/gfxwidgets.h>
struct grub_gfxmenu_view; /* Forward declaration of opaque type. */
typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t;
grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path,
int width, int height);
void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view);
/* Set properties on the view based on settings from the specified
theme file. */
grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view,
const char *theme_path);
grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
const char *pattern, const char *theme_dir);
void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view);
void
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view);
void
grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view);
void
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
const grub_video_rect_t *region);
void
grub_gfxmenu_clear_timeout (void *data);
void
grub_gfxmenu_print_timeout (int timeout, void *data);
void
grub_gfxmenu_set_chosen_entry (int entry, void *data);
void
grub_gfxmenu_scroll_chosen_entry (void *data, int diren);
grub_err_t grub_font_draw_string (const char *str,
grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y);
int grub_font_get_string_width (grub_font_t font,
const char *str);
/* Implementation details -- this should not be used outside of the
view itself. */
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/bitmap_scale.h>
#include <grub/gui.h>
#include <grub/gfxwidgets.h>
#include <grub/icon_manager.h>
/* Definition of the private representation of the view. */
struct grub_gfxmenu_view
{
grub_video_rect_t screen;
int need_to_check_sanity;
grub_video_rect_t terminal_rect;
int terminal_border;
grub_font_t title_font;
grub_font_t message_font;
char *terminal_font_name;
grub_video_rgba_color_t title_color;
grub_video_rgba_color_t message_color;
grub_video_rgba_color_t message_bg_color;
struct grub_video_bitmap *raw_desktop_image;
struct grub_video_bitmap *scaled_desktop_image;
grub_video_bitmap_selection_method_t desktop_image_scale_method;
grub_video_bitmap_h_align_t desktop_image_h_align;
grub_video_bitmap_v_align_t desktop_image_v_align;
grub_video_rgba_color_t desktop_color;
grub_gfxmenu_box_t terminal_box;
char *title_text;
char *progress_message_text;
char *theme_path;
grub_gui_container_t canvas;
int double_repaint;
int selected;
grub_video_rect_t progress_message_frame;
grub_menu_t menu;
int nested;
int first_timeout;
int *menu_title_offset;
};
#endif /* ! GRUB_GFXMENU_VIEW_HEADER */

View File

@ -0,0 +1,49 @@
/* menu_viewer.h - Interface to menu viewer implementations. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#ifndef GRUB_MENU_VIEWER_HEADER
#define GRUB_MENU_VIEWER_HEADER 1
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/menu.h>
#include <grub/term.h>
struct grub_menu_viewer
{
struct grub_menu_viewer *next;
void *data;
void (*set_chosen_entry) (int entry, void *data);
void (*scroll_chosen_entry) (void *data, int diren);
void (*print_timeout) (int timeout, void *data);
void (*clear_timeout) (void *data);
void (*fini) (void *fini);
};
void grub_menu_register_viewer (struct grub_menu_viewer *viewer);
grub_err_t
grub_menu_try_text (struct grub_term_output *term,
int entry, grub_menu_t menu, int nested);
extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
int nested);
#endif /* GRUB_MENU_VIEWER_HEADER */

View File

@ -0,0 +1,69 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2019 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_SMBIOS_HEADER
#define GRUB_SMBIOS_HEADER 1
#include <grub/symbol.h>
#include <grub/types.h>
#define GRUB_SMBIOS_TYPE_END_OF_TABLE ((grub_uint8_t)127)
struct grub_smbios_ieps
{
grub_uint8_t anchor[5]; /* "_DMI_" */
grub_uint8_t checksum;
grub_uint16_t table_length;
grub_uint32_t table_address;
grub_uint16_t structures;
grub_uint8_t revision;
} GRUB_PACKED;
struct grub_smbios_eps
{
grub_uint8_t anchor[4]; /* "_SM_" */
grub_uint8_t checksum;
grub_uint8_t length; /* 0x1f */
grub_uint8_t version_major;
grub_uint8_t version_minor;
grub_uint16_t maximum_structure_size;
grub_uint8_t revision;
grub_uint8_t formatted[5];
struct grub_smbios_ieps intermediate;
} GRUB_PACKED;
struct grub_smbios_eps3
{
grub_uint8_t anchor[5]; /* "_SM3_" */
grub_uint8_t checksum;
grub_uint8_t length; /* 0x18 */
grub_uint8_t version_major;
grub_uint8_t version_minor;
grub_uint8_t docrev;
grub_uint8_t revision;
grub_uint8_t reserved;
grub_uint32_t maximum_table_length;
grub_uint64_t table_address;
} GRUB_PACKED;
extern struct grub_smbios_eps *grub_machine_smbios_get_eps (void);
extern struct grub_smbios_eps3 *grub_machine_smbios_get_eps3 (void);
extern struct grub_smbios_eps *EXPORT_FUNC (grub_smbios_get_eps) (void);
#endif /* ! GRUB_SMBIOS_HEADER */

View File

@ -121,6 +121,9 @@ typedef struct ventoy_os_param
* vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows 2:wimfile * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows 2:wimfile
* vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf * vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf
* vtoy_reserved[4]: vtoy_windows_cd_prompt * vtoy_reserved[4]: vtoy_windows_cd_prompt
* vtoy_reserved[5]: vtoy_linux_remount
* vtoy_reserved[6]: vtoy_vlnk
* vtoy_reserved[7~10]: vtoy_disk_sig[4] used for vlnk
* *
*/ */
grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy
@ -136,7 +139,15 @@ typedef struct ventoy_windows_data
char auto_install_script[384]; char auto_install_script[384];
char injection_archive[384]; char injection_archive[384];
grub_uint8_t windows11_bypass_check; grub_uint8_t windows11_bypass_check;
grub_uint8_t reserved[255];
grub_uint32_t auto_install_len;
grub_uint8_t windows11_bypass_nro;
grub_uint8_t reserved[255 - 5];
/* auto_intall file buf */
/* ...... + auto_install_len */
}ventoy_windows_data; }ventoy_windows_data;
@ -150,11 +161,23 @@ typedef struct ventoy_secure_data
grub_uint8_t magic2[16]; /* VENTOY_GUID */ grub_uint8_t magic2[16]; /* VENTOY_GUID */
}ventoy_secure_data; }ventoy_secure_data;
typedef struct ventoy_vlnk
{
ventoy_guid guid; // VENTOY_GUID
grub_uint32_t crc32; // crc32
grub_uint32_t disk_signature;
grub_uint64_t part_offset; // in bytes
char filepath[384];
grub_uint8_t reserved[96];
}ventoy_vlnk;
#pragma pack() #pragma pack()
// compile assert check : sizeof(ventoy_os_param) must be 512 // compile assert check : sizeof(ventoy_os_param) must be 512
COMPILE_ASSERT(1,sizeof(ventoy_os_param) == 512); COMPILE_ASSERT(1,sizeof(ventoy_os_param) == 512);
COMPILE_ASSERT(2,sizeof(ventoy_secure_data) == 4096); COMPILE_ASSERT(2,sizeof(ventoy_secure_data) == 4096);
COMPILE_ASSERT(3,sizeof(ventoy_vlnk) == 512);
@ -241,6 +264,7 @@ typedef struct ventoy_img_chunk_list
#pragma pack(1) #pragma pack(1)
#define VTOY_MAX_CONF_REPLACE 2
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF #define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
#define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF #define GRUB_IMG_REPLACE_MAGIC 0x1259BEEF
@ -261,7 +285,7 @@ typedef struct ventoy_grub_param
grub_env_get_pf grub_env_get; grub_env_get_pf grub_env_get;
grub_env_set_pf grub_env_set; grub_env_set_pf grub_env_set;
ventoy_grub_param_file_replace file_replace; ventoy_grub_param_file_replace file_replace;
ventoy_grub_param_file_replace img_replace; ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
grub_env_printf_pf grub_env_printf; grub_env_printf_pf grub_env_printf;
}ventoy_grub_param; }ventoy_grub_param;
@ -282,6 +306,7 @@ grub_uint64_t grub_udf_get_last_file_attr_offset
grub_uint64_t *fe_entry_size_offset grub_uint64_t *fe_entry_size_offset
); );
int ventoy_is_efi_os(void); int ventoy_is_efi_os(void);
void ventoy_memfile_env_set(const char *prefix, const void *buf, unsigned long long len);
#endif /* __VENTOY_H__ */ #endif /* __VENTOY_H__ */

View File

@ -9,17 +9,17 @@ mkdir -p $VT_DIR/GRUB2/PXE
make install make install
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/ PATH=$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/:$PATH
net_modules_legacy="net tftp http" net_modules_legacy="net tftp http"
all_modules_legacy="file setkey date drivemap blocklist regexp newc vga_text 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_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" all_modules_legacy="file date drivemap blocklist newc vga_text 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 font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal video_fb udf gfxmenu gfxterm gfxterm_background gfxterm_menu smbios"
net_modules_uefi="efinet net tftp http" net_modules_uefi="efinet net tftp http"
all_modules_uefi="file setkey blocklist ventoy test true regexp newc 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" all_modules_uefi="file setkey blocklist ventoy test true regexp newc 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 mouse fwload smbios zfs"
all_modules_arm64_uefi="file setkey blocklist ventoy test true regexp newc search 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 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 video video_fb gfxterm_background gfxterm_menu" all_modules_arm64_uefi="file setkey blocklist ventoy test true regexp newc search 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 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 video video_fb gfxterm_background gfxterm_menu zfs"
all_modules_mips64el_uefi="file setkey blocklist ventoy test true regexp newc search 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 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 video video_fb gfxterm_background gfxterm_menu" all_modules_mips64el_uefi="file setkey blocklist ventoy test true regexp newc search 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 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 video video_fb gfxterm_background gfxterm_menu zfs"
if [ "$1" = "uefi" ]; then if [ "$1" = "uefi" ]; then

View File

@ -1165,6 +1165,7 @@ main (int argc, char *argv[])
break; break;
case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
efi_file = "grubmips64el.efi"; efi_file = "grubmips64el.efi";
break;
case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
efi_file = "grubriscv32.efi"; efi_file = "grubriscv32.efi";
break; break;

BIN
ICON/filechecksum.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

View File

@ -48,6 +48,12 @@ else
fi fi
fi fi
if [ "$VTOY_ARCH" = "i386" ]; then
if $BUSYBOX_PATH/vtchmod32 -6; then
export VTOY_ARCH=x86_64
fi
fi
echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch
@ -81,6 +87,7 @@ export PATH=$BUSYBOX_PATH/:$VTOY_PATH/tool
export VTOY_BREAK_LEVEL=$(hexdump -n 1 -s 449 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) export VTOY_BREAK_LEVEL=$(hexdump -n 1 -s 449 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
export VTOY_DEBUG_LEVEL=$(hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param) export VTOY_DEBUG_LEVEL=$(hexdump -n 1 -s 450 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
export VTOY_LINUX_REMOUNT=$(hexdump -n 1 -s 454 -e '1/1 "%02x"' $VTOY_PATH/ventoy_os_param)
#Fixme: busybox shell output redirect seems to have some bug in rhel5 #Fixme: busybox shell output redirect seems to have some bug in rhel5
if uname -a | grep -q el5; then if uname -a | grep -q el5; then
@ -108,6 +115,8 @@ fi
if [ "$VTOY_ARCH" = "x86_64" ]; then if [ "$VTOY_ARCH" = "x86_64" ]; then
echo "Use x86_64 busybox toolkit ..." >>$VTLOG echo "Use x86_64 busybox toolkit ..." >>$VTLOG
$BUSYBOX_PATH/xzcat $BUSYBOX_PATH/xzcat64_musl.xz > $BUSYBOX_PATH/xzcat_musl
$BUSYBOX_PATH/chmod +x $BUSYBOX_PATH/xzcat_musl
ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec
ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup
ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip
@ -117,6 +126,8 @@ if [ "$VTOY_ARCH" = "x86_64" ]; then
ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat
elif [ "$VTOY_ARCH" = "i386" ]; then elif [ "$VTOY_ARCH" = "i386" ]; then
echo "Use i386 busybox toolkit ..." >>$VTLOG echo "Use i386 busybox toolkit ..." >>$VTLOG
$BUSYBOX_PATH/xzcat $BUSYBOX_PATH/xzcat32_musl.xz > $BUSYBOX_PATH/xzcat_musl
$BUSYBOX_PATH/chmod +x $BUSYBOX_PATH/xzcat_musl
ln -s $BUSYBOX_PATH/xzminidec32 $BUSYBOX_PATH/xzminidec ln -s $BUSYBOX_PATH/xzminidec32 $BUSYBOX_PATH/xzminidec
ln -s $VTOY_PATH/tool/dmsetup32 $VTOY_PATH/tool/dmsetup ln -s $VTOY_PATH/tool/dmsetup32 $VTOY_PATH/tool/dmsetup
ln -s $VTOY_PATH/tool/lunzip32 $VTOY_PATH/tool/lunzip ln -s $VTOY_PATH/tool/lunzip32 $VTOY_PATH/tool/lunzip

View File

@ -0,0 +1,4 @@
for i in 1 2; do
if [ $i -eq 2 ]; then
/ventoy/busybox/sh /ventoy/hook/alpine/udev_disk_hook.sh
fi

View File

@ -19,22 +19,17 @@
. /ventoy/hook/ventoy-hook-lib.sh . /ventoy/hook/ventoy-hook-lib.sh
if [ "$SUBSYSTEM" != "block" ] || [ "$DEVTYPE" != "partition" ]; then
exit 0
fi
if [ -b /dev/${MDEV:0:-1} ]; then
vtlog "/dev/${MDEV:0:-1} exist"
else
$SLEEP 2
fi
if is_ventoy_hook_finished || not_ventoy_disk "${MDEV:0:-1}"; then
exit 0
fi
PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
wait_for_usb_disk_ready
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
# #
# longpanda: # longpanda:
# Alpine initramfs doesn't contain dm-mod or fuse module, # Alpine initramfs doesn't contain dm-mod or fuse module,
@ -47,13 +42,17 @@ PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
# 3. unmount and delete the squashfs file # 3. unmount and delete the squashfs file
# #
MDEV="${vtdiskname#/dev/}2"
vtoydm -i -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} > $VTOY_PATH/iso_file_list vtoydm -i -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} > $VTOY_PATH/iso_file_list
vtLine=$(grep '[-][-] modloop-lts ' $VTOY_PATH/iso_file_list) vtLine=$(grep '[-][-] modloop-lts ' $VTOY_PATH/iso_file_list)
sector=$(echo $vtLine | awk '{print $(NF-1)}') sector=$(echo $vtLine | awk '{print $(NF-1)}')
length=$(echo $vtLine | awk '{print $NF}') length=$(echo $vtLine | awk '{print $NF}')
echo -n "Mounting boot media, please wait ......"
vtoydm -e -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} -s $sector -l $length -o /vt_modloop vtoydm -e -f $VTOY_PATH/ventoy_image_map -d /dev/${MDEV:0:-1} -s $sector -l $length -o /vt_modloop
echo "done"
mkdir -p $VTOY_PATH/mnt mkdir -p $VTOY_PATH/mnt
mount /vt_modloop $VTOY_PATH/mnt mount /vt_modloop $VTOY_PATH/mnt

View File

@ -19,6 +19,17 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
echo "-[-a-z0-9]*2 root:root 0666 @$BUSYBOX_PATH/sh $VTOY_PATH/hook/alpine/udev_disk_hook.sh" >> /mdev.conf PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
$CAT /etc/mdev.conf >> /mdev.conf
$BUSYBOX_PATH/mv /mdev.conf /etc/mdev.conf LineBegin=$(grep -n "ebegin.*Mounting boot media" /init | awk -F: '{print $1}')
grep -n "^eend" /init > /t.list
while read line; do
LineEnd=$(echo $line | awk -F: '{print $1}')
if [ $LineEnd -gt $LineBegin ]; then
sed "${LineEnd}i\done" -i /init
sed "${LineBegin}r /ventoy/hook/alpine/insert.sh" -i /init
break
fi
done < /t.list
rm -f /t.list

View File

@ -49,7 +49,12 @@ done
if [ -n "$1" ]; then if [ -n "$1" ]; then
vtlog "ln -s /dev/$vtDM $1" vtlog "ln -s /dev/$vtDM $1"
if [ -e "$1" ]; then
vtlog "$1 already exist"
else
ln -s /dev/$vtDM "$1" ln -s /dev/$vtDM "$1"
fi
else else
vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/')
vtlog "vtLABEL is $vtLABEL" vtlog "vtLABEL is $vtLABEL"
@ -59,7 +64,11 @@ else
vtlog "vtLABEL is $vtLABEL from cmdline" vtlog "vtLABEL is $vtLABEL from cmdline"
fi fi
if [ -e "/dev/disk/by-label/$vtLABEL" ]; then
vtlog "$1 already exist"
else
ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL"
fi
fi fi
# OK finish # OK finish

View File

@ -20,7 +20,7 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
if $GREP -q '^"$mount_handler"' /init; then if $GREP -q '^"$mount_handler"' /init; then
echo 'use mount_handler ...' >> $VTLOG echo 'use mount_handler1 ...' >> $VTLOG
vthookfile=/hooks/archiso vthookfile=/hooks/archiso
@ -37,6 +37,9 @@ if $GREP -q '^"$mount_handler"' /init; then
if [ -f $vthookfile ]; then if [ -f $vthookfile ]; then
$SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile
fi fi
elif $GREP -q '^$mount_handler' /init; then
echo 'use mount_handler2 ...' >> $VTLOG
$SED "/^\$mount_handler/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh" -i /init
elif $GREP -q '^KEEP_SEARCHING' /init; then elif $GREP -q '^KEEP_SEARCHING' /init; then
echo 'KEEP_SEARCHING found ...' >> $VTLOG echo 'KEEP_SEARCHING found ...' >> $VTLOG

View File

@ -20,7 +20,7 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
$BUSYBOX_PATH/mkdir /dev $BUSYBOX_PATH/mkdir /dev
$BUSYBOX_PATH/mknod -m 660 /dev/console b 5 1 $BUSYBOX_PATH/mknod -m 660 /dev/console c 5 1
$SED "/for device in/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/aryalinux/disk_hook.sh" -i /init $SED "/for device in/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/aryalinux/disk_hook.sh" -i /init
#$SED "/for device in/i exec $BUSYBOX_PATH/sh" -i /init #$SED "/for device in/i exec $BUSYBOX_PATH/sh" -i /init

View File

@ -22,4 +22,4 @@
ventoy_set_inotify_script blackPanther/ventoy-inotifyd-hook.sh ventoy_set_inotify_script blackPanther/ventoy-inotifyd-hook.sh
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/blackPanther/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/00-ventoy-inotifyd-start.sh $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/blackPanther/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/00-ventoy-inotifyd-start.sh
$SED "s#printf\(.*\)\$CMDLINE#printf\1 root=/dev/dm-0 \$CMDLINE root=/dev/dm-0#" -i /lib/dracut-lib.sh $SED "s#printf\(.*\)\$CMDLINE#printf\1 root=/dev/ventoy \$CMDLINE root=/dev/ventoy#" -i /lib/dracut-lib.sh

View File

@ -33,10 +33,8 @@ if is_inotify_ventoy_part $3; then
$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace
blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/')
if ! [ -e /dev/dm-0 ]; then mknod -m 660 /dev/ventoy b $blkdev_num_dev
mknod -m 660 /dev/dm-0 b $blkdev_num_dev blackPanther-root /dev/ventoy
fi
blackPanther-root /dev/dm-0
set_ventoy_hook_finish set_ventoy_hook_finish
else else

View File

@ -0,0 +1,32 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
for i in 0 1 2 3 4 5 6 7 8 9; do
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "wait for disk ..."
$SLEEP 3
else
break
fi
done
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2"

View File

@ -0,0 +1,22 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. $VTOY_PATH/hook/ventoy-os-lib.sh
$SED "/maybe_break *premount/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/chimera/disk_hook.sh" -i /init

View File

@ -0,0 +1,43 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
NEWROOT=$(grep switch_root /init | awk '{print $3}')
for i in 'usr/bin' 'usr/sbin'; do
if [ -f $NEWROOT/$i/udevadm ]; then
UPATH=$i
break
fi
done
blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/')
vtDM=$(ventoy_find_dm_id ${blkdev_num})
sed "s#UPATH=.*#UPATH=/$UPATH#" -i /ventoy/hook/clear/udevadm
sed "s#DM=.*#DM=$vtDM#" -i /ventoy/hook/clear/udevadm
mv $NEWROOT/$UPATH/udevadm $NEWROOT/$UPATH/udevadm_bk
cp -a /ventoy/hook/clear/udevadm $NEWROOT/$UPATH/udevadm
chmod 777 $NEWROOT/$UPATH/udevadm

View File

@ -0,0 +1,12 @@
#!/bin/bash
UPATH=/usr/bin
DM=dm-0
rm -f $UPATH/udevadm
mv $UPATH/udevadm_bk $UPATH/udevadm
echo 1 > /tmp/vthidden
mount --bind /tmp/vthidden /sys/block/$DM/hidden
exec $UPATH/udevadm "$@"

View File

@ -26,3 +26,6 @@ else
echo "find_installer" >> $VTLOG echo "find_installer" >> $VTLOG
$SED "/\$.*find_installer/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init $SED "/\$.*find_installer/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init
fi fi
#issue 1674
$SED "/switch_root/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/hidden-hook.sh" -i /init

View File

@ -19,6 +19,8 @@
. /ventoy/hook/ventoy-hook-lib.sh . /ventoy/hook/ventoy-hook-lib.sh
/sbin/mdev -s
# Just for KVM test environment # Just for KVM test environment
$BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null $BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null
$BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null $BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null
@ -34,3 +36,6 @@ for i in 0 1 2 3 4 5 6 7 8 9; do
done done
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
$BUSYBOX_PATH/rm -f /dev/dm-*

View File

@ -19,6 +19,6 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
$SED "/mount_boot /i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init $SED "/mount_boot[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/daphile/disk_hook.sh" -i /init
$SED "s#'\.\*/block/mmcblk[^ ]*'#'\.\*/block/dm-[0-9]*'#" -i /init $SED "s#'\.\*/block/mmcblk[^ ]*'#'\.\*/block/dm-[0-9]*'#" -i /init

View File

@ -40,13 +40,13 @@ ventoy_os_install_dmsetup_by_unsquashfs() {
dmModPath="/usr/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" dmModPath="/usr/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo"
echo $dmModPath > $VTOY_PATH/fsextract echo $dmModPath > $VTOY_PATH/fsextract
vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk 2>>$VTLOG
if ! [ -e $VTOY_PATH/sqfs${dmModPath} ]; then if ! [ -e $VTOY_PATH/sqfs${dmModPath} ]; then
rm -rf $VTOY_PATH/sqfs rm -rf $VTOY_PATH/sqfs
dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo"
echo $dmModPath > $VTOY_PATH/fsextract echo $dmModPath > $VTOY_PATH/fsextract
vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk 2>>$VTLOG
fi fi
if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then

View File

@ -54,9 +54,20 @@ fi
if [ -f $VTOY_PATH/autoinstall ]; then if [ -f $VTOY_PATH/autoinstall ]; then
echo "Do auto install ..." >> $VTLOG echo "Do auto install ..." >> $VTLOG
if $GREP -q '^autoinstall:' $VTOY_PATH/autoinstall; then
echo "cloud-init auto install ..." >> $VTLOG
if $GREP -q "maybe_break init" /init; then
$SED "/maybe_break init/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/ventoy-cloud-init.sh \$rootmnt" -i /init
fi
else
if $GREP -q "^mount /proc$" /init; then if $GREP -q "^mount /proc$" /init; then
$SED "/^mount \/proc/a export file=$VTOY_PATH/autoinstall; export auto='true'; export priority='critical'" -i /init $SED "/^mount \/proc/a export file=$VTOY_PATH/autoinstall; export auto='true'; export priority='critical'" -i /init
fi fi
fi
# if [ -e /bin/check-missing-firmware ]; then
# $SED "/^#!/a\exit 0" -i /bin/check-missing-firmware
# fi
fi fi
#for ARMA aka Omoikane #for ARMA aka Omoikane

View File

@ -34,3 +34,7 @@ fi
vtlog "${vtdiskname#/dev/}2 found..." vtlog "${vtdiskname#/dev/}2 found..."
$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "${vtdiskname#/dev/}2" $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "${vtdiskname#/dev/}2"
if [ -f /ventoy/autoinstall ]; then
sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall
fi

View File

@ -0,0 +1,82 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
vtlog "####### $0 $* ########"
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
ventoy_os_install_dmsetup_by_fuse() {
vtlog "ventoy_os_install_dmsetup_by_fuse $*"
mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs
vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table
vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse
mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso
mount -t squashfs $VTOY_PATH/mnt/iso/minios/0*-core*.sb $VTOY_PATH/mnt/squashfs
KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*)
vtlog "insmod $KoName"
insmod $KoName
umount $VTOY_PATH/mnt/squashfs
umount $VTOY_PATH/mnt/iso
umount $VTOY_PATH/mnt/fuse
}
ventoy_os_install_dmsetup() {
vtlog "ventoy_os_install_dmsetup"
if grep -q 'device-mapper' /proc/devices; then
vtlog "device-mapper module already loaded"
return;
fi
vtKerVer=$(uname -r)
if modprobe fuse 2>>$VTLOG; then
ventoy_os_install_dmsetup_by_fuse $1 $vtKerVer
fi
}
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
if check_usb_disk_ready "$vtdiskname"; then
vtlog "check_usb_disk_ready ok"
else
vtlog "check_usb_disk_ready error"
PATH=$VTPATH_OLD
exit 0
fi
ventoy_os_install_dmsetup $vtdiskname
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
PATH=$VTPATH_OLD

View File

@ -0,0 +1,24 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
if [ -f /lib/livekitlib ] && $GREP -q 'debug_log.*find_data_try' /lib/livekitlib; then
$SED "/debug_log.*find_data_try/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/minios-disk.sh" -i /lib/livekitlib
else
$SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/minios-disk.sh" -i /init
fi

View File

@ -37,12 +37,20 @@ ventoy_os_install_dmsetup_by_fuse() {
mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso
if ls $VTOY_PATH/mnt/iso/zdrv_*.sfs 2>/dev/null; then
sfsfile=$(ls $VTOY_PATH/mnt/iso/zdrv_*.sfs)
else
sfsfile=$(ls $VTOY_PATH/mnt/iso/*.sfs) sfsfile=$(ls $VTOY_PATH/mnt/iso/*.sfs)
fi
mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs
kVer=$(uname -r) kVer=$(uname -r)
KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*)
if [ -z "$KoName" ]; then
KoName=$(ls $VTOY_PATH/mnt/squashfs/usr/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*)
fi
vtlog "insmod $KoName" vtlog "insmod $KoName"
insmod $KoName insmod $KoName

View File

@ -19,21 +19,28 @@
. /ventoy/hook/ventoy-hook-lib.sh . /ventoy/hook/ventoy-hook-lib.sh
if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then if is_ventoy_hook_finished; then
exit 0 exit 0
fi fi
vtlog "####### $0 $* ########"
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
modprobe fuse wait_for_usb_disk_ready
mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso
vtoydm -p -f $VTOY_PATH/ventoy_image_map -d "/dev/${1:0:-1}" > $VTOY_PATH/ventoy_dm_table vtdiskname=$(get_ventoy_disk_name)
vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse if [ "$vtdiskname" = "unknown" ]; then
mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
# OK finish ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2"
set_ventoy_hook_finish
mkdir /root
chmod -R 0755 /root
PATH=$VTPATH_OLD PATH=$VTPATH_OLD
set_ventoy_hook_finish

View File

@ -0,0 +1,20 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
$SED "/maybe_break *post_modules/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/stratodesk-disk.sh" -i /init

Some files were not shown because too many files have changed in this diff Show More