mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-09-18 09:51:15 +00:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e8d17f9bb1 | ||
|
2283c3e8b0 | ||
|
8bbd5a14a3 | ||
|
f7d7db6a18 | ||
|
147a23c9dd | ||
|
062c71b972 | ||
|
78ab7a0759 | ||
|
3ebd58c9df | ||
|
ce6d379564 | ||
|
40fdfa66b9 | ||
|
9ddee7394d | ||
|
c9b316a757 | ||
|
1ba23bcdff | ||
|
6630ab3585 | ||
|
c0d478c2dd | ||
|
0217c5a923 | ||
|
97312d351e | ||
|
906dc4cd41 | ||
|
82a8b59bc7 | ||
|
b53e1fb8a8 | ||
|
84abffc424 | ||
|
bf4e014023 | ||
|
4f840ed673 | ||
|
d02f184a8d | ||
|
774e38928f | ||
|
0faba673a5 | ||
|
3c649b281f | ||
|
5f409a1208 |
@@ -3,7 +3,7 @@
|
|||||||
1. Compile Enviroment
|
1. Compile Enviroment
|
||||||
==========================================
|
==========================================
|
||||||
My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch.
|
My build envrioment 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 envrioment is important. I suggest you test it on a virtual machine first.
|
Because Ventoy is based on many open source projects, so the environment is important. I suggest you test it on a virtual machine first.
|
||||||
|
|
||||||
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
|
||||||
|
@@ -273,19 +273,33 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
||||||
location->image_sector_size = 2048;
|
location->image_sector_size = gSector512Mode ? 512 : 2048;
|
||||||
location->disk_sector_size = g_chain->disk_sector_size;
|
location->disk_sector_size = g_chain->disk_sector_size;
|
||||||
location->region_count = g_img_chunk_num;
|
location->region_count = g_img_chunk_num;
|
||||||
|
|
||||||
region = location->regions;
|
region = location->regions;
|
||||||
|
|
||||||
for (i = 0; i < g_img_chunk_num; i++)
|
if (gSector512Mode)
|
||||||
{
|
{
|
||||||
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
region->image_start_sector = chunk->img_start_sector;
|
{
|
||||||
region->disk_start_sector = chunk->disk_start_sector;
|
region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
|
||||||
region++;
|
region->image_start_sector = chunk->img_start_sector * 4;
|
||||||
chunk++;
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
||||||
|
region->image_start_sector = chunk->img_start_sector;
|
||||||
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -394,12 +408,12 @@ STATIC VOID ventoy_warn_invalid_device(VOID)
|
|||||||
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n");
|
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n");
|
||||||
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n\r\n\r\n");
|
gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n\r\n\r\n");
|
||||||
|
|
||||||
gST->ConOut->OutputString(gST->ConOut, L"This is NOT a standard Ventoy device and is NOT officially supported.\r\n\r\n");
|
gST->ConOut->OutputString(gST->ConOut, L"This is NOT a standard Ventoy device and is NOT supported.\r\n\r\n");
|
||||||
gST->ConOut->OutputString(gST->ConOut, L"You should follow the official instructions in https://www.ventoy.net\r\n");
|
gST->ConOut->OutputString(gST->ConOut, L"You should follow the official instructions in https://www.ventoy.net\r\n");
|
||||||
|
|
||||||
gST->ConOut->OutputString(gST->ConOut, L"\r\n\r\nWill continue to boot after 15 seconds ...... ");
|
gST->ConOut->OutputString(gST->ConOut, L"\r\n\r\nWill exit after 10 seconds ...... ");
|
||||||
|
|
||||||
sleep(15);
|
sleep(10);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
STATIC VOID ventoy_warn_invalid_device(VOID)
|
STATIC VOID ventoy_warn_invalid_device(VOID)
|
||||||
@@ -704,6 +718,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||||||
if (pEnv[0] != '0' || pEnv[1] != 0)
|
if (pEnv[0] != '0' || pEnv[1] != 0)
|
||||||
{
|
{
|
||||||
ventoy_warn_invalid_device();
|
ventoy_warn_invalid_device();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_file_replace_list = &pGrubParam->file_replace;
|
g_file_replace_list = &pGrubParam->file_replace;
|
||||||
|
@@ -185,7 +185,7 @@ typedef struct ventoy_virt_chunk
|
|||||||
#error Unknown Processor Type
|
#error Unknown Processor Type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VENTOY_DEVICE_WARN 0
|
#define VENTOY_DEVICE_WARN 1
|
||||||
#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
||||||
|
|
||||||
typedef struct ventoy_sector_flag
|
typedef struct ventoy_sector_flag
|
||||||
|
@@ -71,6 +71,7 @@ STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL;
|
|||||||
|
|
||||||
STATIC UINT8 g_sector_buf[2048];
|
STATIC UINT8 g_sector_buf[2048];
|
||||||
STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
|
STATIC EFI_BLOCK_READ g_sector_2048_read = NULL;
|
||||||
|
STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL;
|
||||||
|
|
||||||
BOOLEAN ventoy_is_cdrom_dp_exist(VOID)
|
BOOLEAN ventoy_is_cdrom_dp_exist(VOID)
|
||||||
{
|
{
|
||||||
@@ -245,6 +246,87 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector
|
||||||
|
(
|
||||||
|
IN UINT64 Sector,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
EFI_LBA MapLba = 0;
|
||||||
|
UINT32 i = 0;
|
||||||
|
UINTN secLeft = 0;
|
||||||
|
UINTN secRead = 0;
|
||||||
|
UINT64 ReadStart = 0;
|
||||||
|
UINT64 ReadEnd = 0;
|
||||||
|
UINT8 *pCurBuf = (UINT8 *)Buffer;
|
||||||
|
ventoy_img_chunk *pchunk = g_chunk;
|
||||||
|
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
|
||||||
|
|
||||||
|
debug("write iso sector %lu count %u", Sector, Count);
|
||||||
|
|
||||||
|
ReadStart = Sector * 2048;
|
||||||
|
ReadEnd = (Sector + Count) * 2048;
|
||||||
|
|
||||||
|
for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++)
|
||||||
|
{
|
||||||
|
if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector)
|
||||||
|
{
|
||||||
|
if (g_chain->disk_sector_size == 512)
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
secLeft = pchunk->img_end_sector + 1 - Sector;
|
||||||
|
secRead = (Count < secLeft) ? Count : secLeft;
|
||||||
|
|
||||||
|
Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
|
||||||
|
MapLba, secRead * 2048, pCurBuf);
|
||||||
|
if (EFI_ERROR(Status))
|
||||||
|
{
|
||||||
|
debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Count -= secRead;
|
||||||
|
Sector += secRead;
|
||||||
|
pCurBuf += secRead * 2048;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_write
|
||||||
|
(
|
||||||
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(VOID)This;
|
||||||
|
(VOID)MediaId;
|
||||||
|
(VOID)Lba;
|
||||||
|
(VOID)BufferSize;
|
||||||
|
(VOID)Buffer;
|
||||||
|
|
||||||
|
if (!gSector512Mode)
|
||||||
|
{
|
||||||
|
return EFI_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
|
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
|
||||||
(
|
(
|
||||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
@@ -438,12 +520,21 @@ EFI_STATUS EFIAPI ventoy_block_io_write
|
|||||||
IN VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT32 secNum = 0;
|
||||||
|
UINT64 offset = 0;
|
||||||
|
|
||||||
(VOID)This;
|
(VOID)This;
|
||||||
(VOID)MediaId;
|
(VOID)MediaId;
|
||||||
(VOID)Lba;
|
|
||||||
(VOID)BufferSize;
|
if (!gSector512Mode)
|
||||||
(VOID)Buffer;
|
{
|
||||||
return EFI_WRITE_PROTECTED;
|
return EFI_WRITE_PROTECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
secNum = BufferSize / 2048;
|
||||||
|
offset = Lba * 2048;
|
||||||
|
|
||||||
|
return ventoy_write_iso_sector(Lba, secNum, Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
||||||
@@ -633,6 +724,68 @@ EFI_STATUS EFIAPI ventoy_block_io_read_512
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EFI_STATUS EFIAPI ventoy_block_io_write_512
|
||||||
|
(
|
||||||
|
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||||
|
IN UINT32 MediaId,
|
||||||
|
IN EFI_LBA Lba,
|
||||||
|
IN UINTN BufferSize,
|
||||||
|
IN VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_LBA Mod;
|
||||||
|
UINTN ReadSize;
|
||||||
|
UINT8 *CurBuf = NULL;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512);
|
||||||
|
|
||||||
|
CurBuf = (UINT8 *)Buffer;
|
||||||
|
|
||||||
|
Mod = Lba % 4;
|
||||||
|
if (Mod > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
if (BufferSize <= (4 - Mod) * 512)
|
||||||
|
{
|
||||||
|
CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize);
|
||||||
|
return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadSize = (4 - Mod) * 512;
|
||||||
|
CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize);
|
||||||
|
g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
Lba += (4 - Mod);
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize >= 2048)
|
||||||
|
{
|
||||||
|
ReadSize = BufferSize / 2048 * 2048;
|
||||||
|
|
||||||
|
Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf);
|
||||||
|
CurBuf += ReadSize;
|
||||||
|
|
||||||
|
Lba += ReadSize / 512;
|
||||||
|
BufferSize -= ReadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize > 0)
|
||||||
|
{
|
||||||
|
Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
|
||||||
|
CopyMem(g_sector_buf, CurBuf, BufferSize);
|
||||||
|
g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
|
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
@@ -665,14 +818,16 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im
|
|||||||
if (gSector512Mode)
|
if (gSector512Mode)
|
||||||
{
|
{
|
||||||
g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
||||||
|
g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write;
|
||||||
pBlockIo->ReadBlocks = ventoy_block_io_read_512;
|
pBlockIo->ReadBlocks = ventoy_block_io_read_512;
|
||||||
|
pBlockIo->WriteBlocks = ventoy_block_io_write_512;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
|
||||||
|
pBlockIo->WriteBlocks = ventoy_block_io_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBlockIo->WriteBlocks = ventoy_block_io_write;
|
|
||||||
pBlockIo->FlushBlocks = ventoy_block_io_flush;
|
pBlockIo->FlushBlocks = ventoy_block_io_flush;
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
|
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
|
||||||
|
839
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
Normal file
839
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
Normal file
@@ -0,0 +1,839 @@
|
|||||||
|
/* theme_loader.c - Theme file loader for gfxmenu. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/video.h>
|
||||||
|
#include <grub/gui_string_util.h>
|
||||||
|
#include <grub/bitmap.h>
|
||||||
|
#include <grub/bitmap_scale.h>
|
||||||
|
#include <grub/gfxwidgets.h>
|
||||||
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/gui.h>
|
||||||
|
#include <grub/color.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop);
|
||||||
|
|
||||||
|
/* Construct a new box widget using ABSPATTERN to find the pixmap files for
|
||||||
|
it, storing the new box instance at *BOXPTR.
|
||||||
|
PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
|
||||||
|
The '*' then gets substituted with the various pixmap names that the
|
||||||
|
box uses. */
|
||||||
|
static grub_err_t
|
||||||
|
recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern)
|
||||||
|
{
|
||||||
|
char *prefix;
|
||||||
|
char *suffix;
|
||||||
|
char *star;
|
||||||
|
grub_gfxmenu_box_t box;
|
||||||
|
|
||||||
|
star = grub_strchr (abspattern, '*');
|
||||||
|
if (! star)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"missing `*' in box pixmap pattern `%s'", abspattern);
|
||||||
|
|
||||||
|
/* Prefix: Get the part before the '*'. */
|
||||||
|
prefix = grub_malloc (star - abspattern + 1);
|
||||||
|
if (! prefix)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
grub_memcpy (prefix, abspattern, star - abspattern);
|
||||||
|
prefix[star - abspattern] = '\0';
|
||||||
|
|
||||||
|
/* Suffix: Everything after the '*' is the suffix. */
|
||||||
|
suffix = star + 1;
|
||||||
|
|
||||||
|
box = grub_gfxmenu_create_box (prefix, suffix);
|
||||||
|
grub_free (prefix);
|
||||||
|
if (! box)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
if (*boxptr)
|
||||||
|
(*boxptr)->destroy (*boxptr);
|
||||||
|
*boxptr = box;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Construct a new box widget using PATTERN to find the pixmap files for it,
|
||||||
|
storing the new widget at *BOXPTR. PATTERN should be of the form:
|
||||||
|
"somewhere/style*.png". The '*' then gets substituted with the various
|
||||||
|
pixmap names that the widget uses.
|
||||||
|
|
||||||
|
Important! The value of *BOXPTR must be initialized! It must either
|
||||||
|
(1) Be 0 (a NULL pointer), or
|
||||||
|
(2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance.
|
||||||
|
In this case, the previous instance is destroyed. */
|
||||||
|
grub_err_t
|
||||||
|
grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
|
||||||
|
const char *pattern, const char *theme_dir)
|
||||||
|
{
|
||||||
|
char *abspattern;
|
||||||
|
|
||||||
|
/* Check arguments. */
|
||||||
|
if (! pattern)
|
||||||
|
{
|
||||||
|
/* If no pixmap pattern is given, then just create an empty box. */
|
||||||
|
if (*boxptr)
|
||||||
|
(*boxptr)->destroy (*boxptr);
|
||||||
|
*boxptr = grub_gfxmenu_create_box (0, 0);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! theme_dir)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"styled box missing theme directory");
|
||||||
|
|
||||||
|
/* Resolve to an absolute path. */
|
||||||
|
abspattern = grub_resolve_relative_path (theme_dir, pattern);
|
||||||
|
if (! abspattern)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
/* Create the box. */
|
||||||
|
recreate_box_absolute (boxptr, abspattern);
|
||||||
|
grub_free (abspattern);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
theme_get_unsigned_int_from_proportional (const char *value,
|
||||||
|
unsigned absolute_value,
|
||||||
|
unsigned int *parsed_value)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
grub_fixed_signed_t frac;
|
||||||
|
signed pixels;
|
||||||
|
err = parse_proportional_spec (value, &pixels, &frac);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels;
|
||||||
|
if (result < 0)
|
||||||
|
result = 0;
|
||||||
|
*parsed_value = result;
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the specified property NAME on the view to the given string VALUE.
|
||||||
|
The caller is responsible for the lifetimes of NAME and VALUE. */
|
||||||
|
static grub_err_t
|
||||||
|
theme_set_string (grub_gfxmenu_view_t view,
|
||||||
|
const char *name,
|
||||||
|
const char *value,
|
||||||
|
const char *theme_dir,
|
||||||
|
const char *filename,
|
||||||
|
int line_num,
|
||||||
|
int col_num)
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("title-font", name))
|
||||||
|
view->title_font = grub_font_get (value);
|
||||||
|
else if (! grub_strcmp ("message-font", name))
|
||||||
|
view->message_font = grub_font_get (value);
|
||||||
|
else if (! grub_strcmp ("terminal-font", name))
|
||||||
|
{
|
||||||
|
grub_free (view->terminal_font_name);
|
||||||
|
view->terminal_font_name = grub_strdup (value);
|
||||||
|
if (! view->terminal_font_name)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("title-color", name))
|
||||||
|
grub_video_parse_color (value, &view->title_color);
|
||||||
|
else if (! grub_strcmp ("message-color", name))
|
||||||
|
grub_video_parse_color (value, &view->message_color);
|
||||||
|
else if (! grub_strcmp ("message-bg-color", name))
|
||||||
|
grub_video_parse_color (value, &view->message_bg_color);
|
||||||
|
else if (! grub_strcmp ("desktop-image", name))
|
||||||
|
{
|
||||||
|
struct grub_video_bitmap *raw_bitmap;
|
||||||
|
char *path;
|
||||||
|
path = grub_resolve_relative_path (theme_dir, value);
|
||||||
|
if (! path)
|
||||||
|
return grub_errno;
|
||||||
|
if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE)
|
||||||
|
{
|
||||||
|
grub_free (path);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
grub_free(path);
|
||||||
|
grub_video_bitmap_destroy (view->raw_desktop_image);
|
||||||
|
view->raw_desktop_image = raw_bitmap;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-scale-method", name))
|
||||||
|
{
|
||||||
|
if (! value || ! grub_strcmp ("stretch", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH;
|
||||||
|
else if (! grub_strcmp ("crop", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP;
|
||||||
|
else if (! grub_strcmp ("padding", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING;
|
||||||
|
else if (! grub_strcmp ("fitwidth", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH;
|
||||||
|
else if (! grub_strcmp ("fitheight", value))
|
||||||
|
view->desktop_image_scale_method =
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported scale method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-h-align", name))
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("left", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT;
|
||||||
|
else if (! grub_strcmp ("center", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER;
|
||||||
|
else if (! grub_strcmp ("right", value))
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported horizontal align method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-image-v-align", name))
|
||||||
|
{
|
||||||
|
if (! grub_strcmp ("top", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP;
|
||||||
|
else if (! grub_strcmp ("center", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER;
|
||||||
|
else if (! grub_strcmp ("bottom", value))
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Unsupported vertical align method: %s",
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("desktop-color", name))
|
||||||
|
grub_video_parse_color (value, &view->desktop_color);
|
||||||
|
else if (! grub_strcmp ("terminal-box", name))
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-border", name))
|
||||||
|
{
|
||||||
|
view->terminal_border = grub_strtoul (value, 0, 10);
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-left", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.width,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.x = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-top", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.height,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.y = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-width", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.width,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.width = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("terminal-height", name))
|
||||||
|
{
|
||||||
|
unsigned int tmp;
|
||||||
|
int err = theme_get_unsigned_int_from_proportional (value,
|
||||||
|
view->screen.height,
|
||||||
|
&tmp);
|
||||||
|
if (err != GRUB_ERR_NONE)
|
||||||
|
return err;
|
||||||
|
view->terminal_rect.height = tmp;
|
||||||
|
}
|
||||||
|
else if (! grub_strcmp ("title-text", name))
|
||||||
|
{
|
||||||
|
grub_free (view->title_text);
|
||||||
|
view->title_text = grub_strdup (value);
|
||||||
|
if (! view->title_text)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"%s:%d:%d unknown property `%s'",
|
||||||
|
filename, line_num, col_num, name);
|
||||||
|
}
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct parsebuf
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int pos;
|
||||||
|
int len;
|
||||||
|
int line_num;
|
||||||
|
int col_num;
|
||||||
|
const char *filename;
|
||||||
|
char *theme_dir;
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
has_more (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
return p->pos < p->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_char (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
if (has_more (p))
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
c = p->buf[p->pos++];
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
p->line_num++;
|
||||||
|
p->col_num = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->col_num++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
peek_char (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
if (has_more (p))
|
||||||
|
return p->buf[p->pos];
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_whitespace (char c)
|
||||||
|
{
|
||||||
|
return (c == ' '
|
||||||
|
|| c == '\t'
|
||||||
|
|| c == '\r'
|
||||||
|
|| c == '\n'
|
||||||
|
|| c == '\f');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
skip_whitespace (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
while (has_more (p) && is_whitespace(peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
advance_to_next_line (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* Eat characters up to the newline. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = read_char (p);
|
||||||
|
}
|
||||||
|
while (c != -1 && c != '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_identifier_char (int c)
|
||||||
|
{
|
||||||
|
return (c != -1
|
||||||
|
&& (grub_isalpha(c)
|
||||||
|
|| grub_isdigit(c)
|
||||||
|
|| c == '_'
|
||||||
|
|| c == '-'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_identifier (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
/* Index of the first character of the identifier in p->buf. */
|
||||||
|
int start;
|
||||||
|
/* Next index after the last character of the identifer in p->buf. */
|
||||||
|
int end;
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Capture the start of the identifier. */
|
||||||
|
start = p->pos;
|
||||||
|
|
||||||
|
/* Scan for the end. */
|
||||||
|
while (is_identifier_char (peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
|
||||||
|
if (end - start < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return grub_new_substring (p->buf, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_expression (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (peek_char (p) == '"')
|
||||||
|
{
|
||||||
|
/* Read as a quoted string.
|
||||||
|
The quotation marks are not included in the expression value. */
|
||||||
|
/* Skip opening quotation mark. */
|
||||||
|
read_char (p);
|
||||||
|
start = p->pos;
|
||||||
|
while (has_more (p) && peek_char (p) != '"')
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
/* Skip the terminating quotation mark. */
|
||||||
|
read_char (p);
|
||||||
|
}
|
||||||
|
else if (peek_char (p) == '(')
|
||||||
|
{
|
||||||
|
/* Read as a parenthesized string -- for tuples/coordinates. */
|
||||||
|
/* The parentheses are included in the expression value. */
|
||||||
|
int c;
|
||||||
|
|
||||||
|
start = p->pos;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = read_char (p);
|
||||||
|
}
|
||||||
|
while (c != -1 && c != ')');
|
||||||
|
end = p->pos;
|
||||||
|
}
|
||||||
|
else if (has_more (p))
|
||||||
|
{
|
||||||
|
/* Read as a single word -- for numeric values or words without
|
||||||
|
whitespace. */
|
||||||
|
start = p->pos;
|
||||||
|
while (has_more (p) && ! is_whitespace (peek_char (p)))
|
||||||
|
read_char (p);
|
||||||
|
end = p->pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The end of the theme file has been reached. */
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return grub_new_substring (p->buf, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop)
|
||||||
|
{
|
||||||
|
signed num;
|
||||||
|
const char *ptr;
|
||||||
|
int sig = 0;
|
||||||
|
*abs = 0;
|
||||||
|
*prop = 0;
|
||||||
|
ptr = value;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
sig = 0;
|
||||||
|
|
||||||
|
while (*ptr == '-' || *ptr == '+')
|
||||||
|
{
|
||||||
|
if (*ptr == '-')
|
||||||
|
sig = !sig;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = grub_strtoul (ptr, (char **) &ptr, 0);
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
if (sig)
|
||||||
|
num = -num;
|
||||||
|
if (*ptr == '%')
|
||||||
|
{
|
||||||
|
*prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*abs += num;
|
||||||
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read a GUI object specification from the theme file.
|
||||||
|
Any components created will be added to the GUI container PARENT. */
|
||||||
|
static grub_err_t
|
||||||
|
read_object (struct parsebuf *p, grub_gui_container_t parent)
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
name = read_identifier (p);
|
||||||
|
if (! name)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
grub_gui_component_t component = 0;
|
||||||
|
if (grub_strcmp (name, "label") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_label_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "image") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_image_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "vbox") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_vbox_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "hbox") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_hbox_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "canvas") == 0)
|
||||||
|
{
|
||||||
|
component = (grub_gui_component_t) grub_gui_canvas_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "progress_bar") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_progress_bar_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "circular_progress") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_circular_progress_new ();
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (name, "boot_menu") == 0)
|
||||||
|
{
|
||||||
|
component = grub_gui_list_new ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown type. */
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! component)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Inform the component about the theme so it can find its resources. */
|
||||||
|
component->ops->set_property (component, "theme_dir", p->theme_dir);
|
||||||
|
component->ops->set_property (component, "theme_path", p->filename);
|
||||||
|
|
||||||
|
/* Add the component as a child of PARENT. */
|
||||||
|
bounds.x = 0;
|
||||||
|
bounds.y = 0;
|
||||||
|
bounds.width = -1;
|
||||||
|
bounds.height = -1;
|
||||||
|
component->ops->set_bounds (component, &bounds);
|
||||||
|
parent->ops->add (parent, component);
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (read_char (p) != '{')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d expected `{' after object type name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (has_more (p))
|
||||||
|
{
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Check whether the end has been encountered. */
|
||||||
|
if (peek_char (p) == '}')
|
||||||
|
{
|
||||||
|
/* Skip the closing brace. */
|
||||||
|
read_char (p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peek_char (p) == '#')
|
||||||
|
{
|
||||||
|
/* Skip comments. */
|
||||||
|
advance_to_next_line (p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peek_char (p) == '+')
|
||||||
|
{
|
||||||
|
/* Skip the '+'. */
|
||||||
|
read_char (p);
|
||||||
|
|
||||||
|
/* Check whether this component is a container. */
|
||||||
|
if (component->ops->is_instance (component, "container"))
|
||||||
|
{
|
||||||
|
/* Read the sub-object recursively and add it as a child. */
|
||||||
|
if (read_object (p, (grub_gui_container_t) component) != 0)
|
||||||
|
goto cleanup;
|
||||||
|
/* After reading the sub-object, resume parsing, expecting
|
||||||
|
another property assignment or sub-object definition. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d attempted to add object to non-container",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *property;
|
||||||
|
property = read_identifier (p);
|
||||||
|
if (! property)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_whitespace (p);
|
||||||
|
if (read_char (p) != '=')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d expected `=' after property name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, property);
|
||||||
|
grub_free (property);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
char *value;
|
||||||
|
value = read_expression (p);
|
||||||
|
if (! value)
|
||||||
|
{
|
||||||
|
grub_free (property);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the property value. */
|
||||||
|
if (grub_strcmp (property, "left") == 0)
|
||||||
|
parse_proportional_spec (value, &component->x, &component->xfrac);
|
||||||
|
else if (grub_strcmp (property, "top") == 0)
|
||||||
|
parse_proportional_spec (value, &component->y, &component->yfrac);
|
||||||
|
else if (grub_strcmp (property, "width") == 0)
|
||||||
|
parse_proportional_spec (value, &component->w, &component->wfrac);
|
||||||
|
else if (grub_strcmp (property, "height") == 0)
|
||||||
|
parse_proportional_spec (value, &component->h, &component->hfrac);
|
||||||
|
else
|
||||||
|
/* General property handling. */
|
||||||
|
component->ops->set_property (component, property, value);
|
||||||
|
|
||||||
|
grub_free (value);
|
||||||
|
grub_free (property);
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
grub_free (name);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
read_property (struct parsebuf *p)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* Read the property name. */
|
||||||
|
name = read_identifier (p);
|
||||||
|
if (! name)
|
||||||
|
{
|
||||||
|
advance_to_next_line (p);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip whitespace before separator. */
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Read separator. */
|
||||||
|
if (read_char (p) != ':')
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d missing separator after property name `%s'",
|
||||||
|
p->filename, p->line_num, p->col_num, name);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip whitespace after separator. */
|
||||||
|
skip_whitespace (p);
|
||||||
|
|
||||||
|
/* Get the value based on its type. */
|
||||||
|
if (peek_char (p) == '"')
|
||||||
|
{
|
||||||
|
/* String value (e.g., '"My string"'). */
|
||||||
|
char *value = read_expression (p);
|
||||||
|
if (! value)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* If theme_set_string results in an error, grub_errno will be returned
|
||||||
|
below. */
|
||||||
|
theme_set_string (p->view, name, value, p->theme_dir,
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
grub_free (value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO,
|
||||||
|
"%s:%d:%d property value invalid; "
|
||||||
|
"enclose literal values in quotes (\")",
|
||||||
|
p->filename, p->line_num, p->col_num);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
grub_free (name);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_file_t file;
|
||||||
|
struct parsebuf p;
|
||||||
|
|
||||||
|
p.view = view;
|
||||||
|
p.theme_dir = grub_get_dirname (theme_path);
|
||||||
|
|
||||||
|
file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME);
|
||||||
|
if (! file)
|
||||||
|
{
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.len = grub_file_size (file);
|
||||||
|
p.buf = grub_malloc (p.len + 4096);
|
||||||
|
p.pos = 0;
|
||||||
|
p.line_num = 1;
|
||||||
|
p.col_num = 1;
|
||||||
|
p.filename = theme_path;
|
||||||
|
if (! p.buf)
|
||||||
|
{
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
if (grub_file_read (file, p.buf, p.len) != p.len)
|
||||||
|
{
|
||||||
|
grub_free (p.buf);
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING");
|
||||||
|
if (checkret == NULL || checkret[0] != '0')
|
||||||
|
{
|
||||||
|
p.len += grub_snprintf(p.buf + p.len, 4096, "\n+ hbox{\n left = 1%%\n top = 90%%\n"
|
||||||
|
" + label {text = \"[Unofficial Ventoy]\" color = \"red\" align = \"left\"}\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
|
||||||
|
view->canvas = grub_gui_canvas_new ();
|
||||||
|
if (!view->canvas)
|
||||||
|
goto fail;
|
||||||
|
((grub_gui_component_t) view->canvas)
|
||||||
|
->ops->set_bounds ((grub_gui_component_t) view->canvas,
|
||||||
|
&view->screen);
|
||||||
|
|
||||||
|
while (has_more (&p))
|
||||||
|
{
|
||||||
|
/* Skip comments (lines beginning with #). */
|
||||||
|
if (peek_char (&p) == '#')
|
||||||
|
{
|
||||||
|
advance_to_next_line (&p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the first non-whitespace character. */
|
||||||
|
skip_whitespace (&p);
|
||||||
|
|
||||||
|
/* Handle the content. */
|
||||||
|
if (peek_char (&p) == '+')
|
||||||
|
{
|
||||||
|
/* Skip the '+'. */
|
||||||
|
read_char (&p);
|
||||||
|
read_object (&p, view->canvas);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_property (&p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_errno != GRUB_ERR_NONE)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new theme path. */
|
||||||
|
grub_free (view->theme_path);
|
||||||
|
view->theme_path = grub_strdup (theme_path);
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (view->canvas)
|
||||||
|
{
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
view->canvas = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
grub_free (p.buf);
|
||||||
|
grub_file_close (file);
|
||||||
|
grub_free (p.theme_dir);
|
||||||
|
return grub_errno;
|
||||||
|
}
|
647
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c
Normal file
647
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c
Normal file
@@ -0,0 +1,647 @@
|
|||||||
|
/* view.c - Graphical menu interface MVC view. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/normal.h>
|
||||||
|
#include <grub/video.h>
|
||||||
|
#include <grub/gfxterm.h>
|
||||||
|
#include <grub/bitmap.h>
|
||||||
|
#include <grub/bitmap_scale.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
#include <grub/gfxwidgets.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
#include <grub/menu.h>
|
||||||
|
#include <grub/menu_viewer.h>
|
||||||
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/gui_string_util.h>
|
||||||
|
#include <grub/icon_manager.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_terminal (grub_gfxmenu_view_t view);
|
||||||
|
static void
|
||||||
|
init_background (grub_gfxmenu_view_t view);
|
||||||
|
static grub_gfxmenu_view_t term_view;
|
||||||
|
|
||||||
|
/* Create a new view object, loading the theme specified by THEME_PATH and
|
||||||
|
associating MODEL with the view. */
|
||||||
|
grub_gfxmenu_view_t
|
||||||
|
grub_gfxmenu_view_new (const char *theme_path,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
grub_font_t default_font;
|
||||||
|
grub_video_rgba_color_t default_fg_color;
|
||||||
|
grub_video_rgba_color_t default_bg_color;
|
||||||
|
|
||||||
|
view = grub_malloc (sizeof (*view));
|
||||||
|
if (! view)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (grub_gfxmenu_timeout_notifications)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *p;
|
||||||
|
p = grub_gfxmenu_timeout_notifications;
|
||||||
|
grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next;
|
||||||
|
grub_free (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
view->screen.x = 0;
|
||||||
|
view->screen.y = 0;
|
||||||
|
view->screen.width = width;
|
||||||
|
view->screen.height = height;
|
||||||
|
|
||||||
|
view->need_to_check_sanity = 1;
|
||||||
|
view->terminal_border = 3;
|
||||||
|
view->terminal_rect.width = view->screen.width * 7 / 10;
|
||||||
|
view->terminal_rect.height = view->screen.height * 7 / 10;
|
||||||
|
view->terminal_rect.x = view->screen.x + (view->screen.width
|
||||||
|
- view->terminal_rect.width) / 2;
|
||||||
|
view->terminal_rect.y = view->screen.y + (view->screen.height
|
||||||
|
- view->terminal_rect.height) / 2;
|
||||||
|
|
||||||
|
default_font = grub_font_get ("Unknown Regular 16");
|
||||||
|
default_fg_color = grub_video_rgba_color_rgb (0, 0, 0);
|
||||||
|
default_bg_color = grub_video_rgba_color_rgb (255, 255, 255);
|
||||||
|
|
||||||
|
view->canvas = 0;
|
||||||
|
|
||||||
|
view->title_font = default_font;
|
||||||
|
view->message_font = default_font;
|
||||||
|
view->terminal_font_name = grub_strdup ("Fixed 10");
|
||||||
|
view->title_color = default_fg_color;
|
||||||
|
view->message_color = default_bg_color;
|
||||||
|
view->message_bg_color = default_fg_color;
|
||||||
|
view->raw_desktop_image = 0;
|
||||||
|
view->scaled_desktop_image = 0;
|
||||||
|
view->desktop_image_scale_method = GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH;
|
||||||
|
view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER;
|
||||||
|
view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER;
|
||||||
|
view->desktop_color = default_bg_color;
|
||||||
|
view->terminal_box = grub_gfxmenu_create_box (0, 0);
|
||||||
|
view->title_text = grub_strdup (_("GRUB Boot Menu"));
|
||||||
|
view->progress_message_text = 0;
|
||||||
|
view->theme_path = 0;
|
||||||
|
|
||||||
|
/* Set the timeout bar's frame. */
|
||||||
|
view->progress_message_frame.width = view->screen.width * 4 / 5;
|
||||||
|
view->progress_message_frame.height = 50;
|
||||||
|
view->progress_message_frame.x = view->screen.x
|
||||||
|
+ (view->screen.width - view->progress_message_frame.width) / 2;
|
||||||
|
view->progress_message_frame.y = view->screen.y
|
||||||
|
+ view->screen.height - 90 - 20 - view->progress_message_frame.height;
|
||||||
|
|
||||||
|
if (grub_gfxmenu_view_load_theme (view, theme_path) != 0)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_destroy (view);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the view object. All used memory is freed. */
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (!view)
|
||||||
|
return;
|
||||||
|
while (grub_gfxmenu_timeout_notifications)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *p;
|
||||||
|
p = grub_gfxmenu_timeout_notifications;
|
||||||
|
grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next;
|
||||||
|
grub_free (p);
|
||||||
|
}
|
||||||
|
grub_video_bitmap_destroy (view->raw_desktop_image);
|
||||||
|
grub_video_bitmap_destroy (view->scaled_desktop_image);
|
||||||
|
if (view->terminal_box)
|
||||||
|
view->terminal_box->destroy (view->terminal_box);
|
||||||
|
grub_free (view->terminal_font_name);
|
||||||
|
grub_free (view->title_text);
|
||||||
|
grub_free (view->progress_message_text);
|
||||||
|
grub_free (view->theme_path);
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->destroy (view->canvas);
|
||||||
|
grub_free (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_background (grub_gfxmenu_view_t view,
|
||||||
|
const grub_video_rect_t *bounds)
|
||||||
|
{
|
||||||
|
if (view->scaled_desktop_image)
|
||||||
|
{
|
||||||
|
struct grub_video_bitmap *img = view->scaled_desktop_image;
|
||||||
|
grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE,
|
||||||
|
bounds->x, bounds->y,
|
||||||
|
bounds->x - view->screen.x,
|
||||||
|
bounds->y - view->screen.y,
|
||||||
|
bounds->width, bounds->height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color),
|
||||||
|
bounds->x, bounds->y,
|
||||||
|
bounds->width, bounds->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_title (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (! view->title_text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Center the title. */
|
||||||
|
int title_width = grub_font_get_string_width (view->title_font,
|
||||||
|
view->title_text);
|
||||||
|
int x = (view->screen.width - title_width) / 2;
|
||||||
|
int y = 40 + grub_font_get_ascent (view->title_font);
|
||||||
|
grub_font_draw_string (view->title_text,
|
||||||
|
view->title_font,
|
||||||
|
grub_video_map_rgba_color (view->title_color),
|
||||||
|
x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct progress_value_data
|
||||||
|
{
|
||||||
|
int visible;
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_timeouts (int visible, int start, int value, int end)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *cur;
|
||||||
|
|
||||||
|
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||||
|
cur->set_state (cur->self, visible, start, value, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_timeouts (struct grub_gfxmenu_view *view)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_timeout_notify *cur;
|
||||||
|
|
||||||
|
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
cur->self->ops->get_bounds (cur->self, &bounds);
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_print_timeout (int timeout, void *data)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_view *view = data;
|
||||||
|
|
||||||
|
if (view->first_timeout == -1)
|
||||||
|
view->first_timeout = timeout;
|
||||||
|
|
||||||
|
update_timeouts (1, -view->first_timeout, -timeout, 0);
|
||||||
|
redraw_timeouts (view);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
redraw_timeouts (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_clear_timeout (void *data)
|
||||||
|
{
|
||||||
|
struct grub_gfxmenu_view *view = data;
|
||||||
|
|
||||||
|
update_timeouts (0, 1, 0, 0);
|
||||||
|
redraw_timeouts (view);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
redraw_timeouts (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_gui_list_t list = (grub_gui_list_t) component;
|
||||||
|
list->ops->set_view_info (list, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update any boot menu components with the current menu model and
|
||||||
|
theme path. */
|
||||||
|
static void
|
||||||
|
update_menu_components (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
update_menu_visit, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
refresh_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_gui_list_t list = (grub_gui_list_t) component;
|
||||||
|
list->ops->refresh_list (list, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Refresh list information (useful for submenus) */
|
||||||
|
static void
|
||||||
|
refresh_menu_components (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
refresh_menu_visit, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_message (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
char *text = view->progress_message_text;
|
||||||
|
grub_video_rect_t f = view->progress_message_frame;
|
||||||
|
if (! text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_font_t font = view->message_font;
|
||||||
|
grub_video_color_t color = grub_video_map_rgba_color (view->message_color);
|
||||||
|
|
||||||
|
/* Border. */
|
||||||
|
grub_video_fill_rect (color,
|
||||||
|
f.x-1, f.y-1, f.width+2, f.height+2);
|
||||||
|
/* Fill. */
|
||||||
|
grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color),
|
||||||
|
f.x, f.y, f.width, f.height);
|
||||||
|
|
||||||
|
/* Center the text. */
|
||||||
|
int text_width = grub_font_get_string_width (font, text);
|
||||||
|
int x = f.x + (f.width - text_width) / 2;
|
||||||
|
int y = (f.y + (f.height - grub_font_get_descent (font)) / 2
|
||||||
|
+ grub_font_get_ascent (font) / 2);
|
||||||
|
grub_font_draw_string (text, font, color, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
|
||||||
|
const grub_video_rect_t *region)
|
||||||
|
{
|
||||||
|
if (grub_video_have_common_points (&view->terminal_rect, region))
|
||||||
|
grub_gfxterm_schedule_repaint ();
|
||||||
|
|
||||||
|
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
|
||||||
|
grub_video_area_status_t area_status;
|
||||||
|
grub_video_get_area_status (&area_status);
|
||||||
|
if (area_status == GRUB_VIDEO_AREA_ENABLED)
|
||||||
|
grub_video_set_region (region->x, region->y,
|
||||||
|
region->width, region->height);
|
||||||
|
|
||||||
|
redraw_background (view, region);
|
||||||
|
if (view->canvas)
|
||||||
|
view->canvas->component.ops->paint (view->canvas, region);
|
||||||
|
draw_title (view);
|
||||||
|
if (grub_video_have_common_points (&view->progress_message_frame, region))
|
||||||
|
draw_message (view);
|
||||||
|
|
||||||
|
if (area_status == GRUB_VIDEO_AREA_ENABLED)
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
init_terminal (view);
|
||||||
|
|
||||||
|
init_background (view);
|
||||||
|
|
||||||
|
/* Clear the screen; there may be garbage left over in video memory. */
|
||||||
|
grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
|
||||||
|
view->screen.x, view->screen.y,
|
||||||
|
view->screen.width, view->screen.height);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
|
||||||
|
view->screen.x, view->screen.y,
|
||||||
|
view->screen.width, view->screen.height);
|
||||||
|
|
||||||
|
refresh_menu_components (view);
|
||||||
|
update_menu_components (view);
|
||||||
|
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->screen);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
{
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
redraw_menu_visit (grub_gui_component_t component,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view;
|
||||||
|
view = userdata;
|
||||||
|
if (component->ops->is_instance (component, "list"))
|
||||||
|
{
|
||||||
|
grub_video_rect_t bounds;
|
||||||
|
|
||||||
|
component->ops->get_bounds (component, &bounds);
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED);
|
||||||
|
grub_gfxmenu_view_redraw (view, &bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
update_menu_components (view);
|
||||||
|
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
redraw_menu_visit, view);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
{
|
||||||
|
grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
|
||||||
|
redraw_menu_visit, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_gfxmenu_set_chosen_entry (int entry, void *data)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = data;
|
||||||
|
|
||||||
|
view->selected = entry;
|
||||||
|
grub_gfxmenu_redraw_menu (view);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_gfxmenu_draw_terminal_box (void)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_box_t term_box;
|
||||||
|
|
||||||
|
term_box = term_view->terminal_box;
|
||||||
|
if (!term_box)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED);
|
||||||
|
|
||||||
|
term_box->set_content_size (term_box, term_view->terminal_rect.width,
|
||||||
|
term_view->terminal_rect.height);
|
||||||
|
|
||||||
|
term_box->draw (term_box,
|
||||||
|
term_view->terminal_rect.x - term_box->get_left_pad (term_box),
|
||||||
|
term_view->terminal_rect.y - term_box->get_top_pad (term_box));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_min_terminal (grub_font_t terminal_font,
|
||||||
|
unsigned int border_width,
|
||||||
|
unsigned int *min_terminal_width,
|
||||||
|
unsigned int *min_terminal_height)
|
||||||
|
{
|
||||||
|
struct grub_font_glyph *glyph;
|
||||||
|
glyph = grub_font_get_glyph (terminal_font, 'M');
|
||||||
|
*min_terminal_width = (glyph? glyph->device_width : 8) * 80
|
||||||
|
+ 2 * border_width;
|
||||||
|
*min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24
|
||||||
|
+ 2 * border_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
terminal_sanity_check (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (!view->need_to_check_sanity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* terminal_font was checked before in the init_terminal function. */
|
||||||
|
grub_font_t terminal_font = grub_font_get (view->terminal_font_name);
|
||||||
|
|
||||||
|
/* Non-negative numbers below. */
|
||||||
|
int scr_x = view->screen.x;
|
||||||
|
int scr_y = view->screen.y;
|
||||||
|
int scr_width = view->screen.width;
|
||||||
|
int scr_height = view->screen.height;
|
||||||
|
int term_x = view->terminal_rect.x;
|
||||||
|
int term_y = view->terminal_rect.y;
|
||||||
|
int term_width = view->terminal_rect.width;
|
||||||
|
int term_height = view->terminal_rect.height;
|
||||||
|
|
||||||
|
/* Check that border_width isn't too big. */
|
||||||
|
unsigned int border_width = view->terminal_border;
|
||||||
|
unsigned int min_terminal_width;
|
||||||
|
unsigned int min_terminal_height;
|
||||||
|
get_min_terminal (terminal_font, border_width,
|
||||||
|
&min_terminal_width, &min_terminal_height);
|
||||||
|
if (border_width > 3 && ((int) min_terminal_width >= scr_width
|
||||||
|
|| (int) min_terminal_height >= scr_height))
|
||||||
|
{
|
||||||
|
border_width = 3;
|
||||||
|
get_min_terminal (terminal_font, border_width,
|
||||||
|
&min_terminal_width, &min_terminal_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity checks. */
|
||||||
|
if (term_width > scr_width)
|
||||||
|
term_width = scr_width;
|
||||||
|
if (term_height > scr_height)
|
||||||
|
term_height = scr_height;
|
||||||
|
|
||||||
|
if (scr_width <= (int) min_terminal_width
|
||||||
|
|| scr_height <= (int) min_terminal_height)
|
||||||
|
{
|
||||||
|
/* The screen resulution is too low. Use all space, except a small border
|
||||||
|
to show the user, that it is a window. Then center the window. */
|
||||||
|
term_width = scr_width - 6 * border_width;
|
||||||
|
term_height = scr_height - 6 * border_width;
|
||||||
|
term_x = scr_x + (scr_width - term_width) / 2;
|
||||||
|
term_y = scr_y + (scr_height - term_height) / 2;
|
||||||
|
}
|
||||||
|
else if (term_width < (int) min_terminal_width
|
||||||
|
|| term_height < (int) min_terminal_height)
|
||||||
|
{
|
||||||
|
/* The screen resolution is big enough. Make sure, that terminal screen
|
||||||
|
dimensions aren't less than minimal values. Then center the window. */
|
||||||
|
term_width = (int) min_terminal_width;
|
||||||
|
term_height = (int) min_terminal_height;
|
||||||
|
term_x = scr_x + (scr_width - term_width) / 2;
|
||||||
|
term_y = scr_y + (scr_height - term_height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point w and h are satisfying. */
|
||||||
|
if (term_x + term_width > scr_width)
|
||||||
|
term_x = scr_width - term_width;
|
||||||
|
if (term_y + term_height > scr_height)
|
||||||
|
term_y = scr_height - term_height;
|
||||||
|
|
||||||
|
/* Write down corrected data. */
|
||||||
|
view->terminal_rect.x = (unsigned int) term_x;
|
||||||
|
view->terminal_rect.y = (unsigned int) term_y;
|
||||||
|
view->terminal_rect.width = (unsigned int) term_width;
|
||||||
|
view->terminal_rect.height = (unsigned int) term_height;
|
||||||
|
view->terminal_border = border_width;
|
||||||
|
|
||||||
|
view->need_to_check_sanity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_terminal (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
grub_font_t terminal_font;
|
||||||
|
|
||||||
|
terminal_font = grub_font_get (view->terminal_font_name);
|
||||||
|
if (!terminal_font)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that terminal window size and position are sane. */
|
||||||
|
terminal_sanity_check (view);
|
||||||
|
|
||||||
|
term_view = view;
|
||||||
|
|
||||||
|
/* Note: currently there is no API for changing the gfxterm font
|
||||||
|
on the fly, so whatever font the initially loaded theme specifies
|
||||||
|
will be permanent. */
|
||||||
|
grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
|
||||||
|
view->terminal_rect.x,
|
||||||
|
view->terminal_rect.y,
|
||||||
|
view->terminal_rect.width,
|
||||||
|
view->terminal_rect.height,
|
||||||
|
view->double_repaint,
|
||||||
|
terminal_font,
|
||||||
|
view->terminal_border);
|
||||||
|
grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_background (grub_gfxmenu_view_t view)
|
||||||
|
{
|
||||||
|
if (view->scaled_desktop_image || (!view->raw_desktop_image))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct grub_video_bitmap *scaled_bitmap;
|
||||||
|
if (view->desktop_image_scale_method ==
|
||||||
|
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH)
|
||||||
|
grub_video_bitmap_create_scaled (&scaled_bitmap,
|
||||||
|
view->screen.width,
|
||||||
|
view->screen.height,
|
||||||
|
view->raw_desktop_image,
|
||||||
|
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
|
||||||
|
else
|
||||||
|
grub_video_bitmap_scale_proportional (&scaled_bitmap,
|
||||||
|
view->screen.width,
|
||||||
|
view->screen.height,
|
||||||
|
view->raw_desktop_image,
|
||||||
|
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST,
|
||||||
|
view->desktop_image_scale_method,
|
||||||
|
view->desktop_image_v_align,
|
||||||
|
view->desktop_image_h_align);
|
||||||
|
if (! scaled_bitmap)
|
||||||
|
return;
|
||||||
|
view->scaled_desktop_image = scaled_bitmap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: previously notifications were displayed in special case.
|
||||||
|
Is it necessary?
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
/* Sets MESSAGE as the progress message for the view.
|
||||||
|
MESSAGE can be 0, in which case no message is displayed. */
|
||||||
|
static void
|
||||||
|
set_progress_message (grub_gfxmenu_view_t view, const char *message)
|
||||||
|
{
|
||||||
|
grub_free (view->progress_message_text);
|
||||||
|
if (message)
|
||||||
|
view->progress_message_text = grub_strdup (message);
|
||||||
|
else
|
||||||
|
view->progress_message_text = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_booting (grub_menu_entry_t entry, void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
|
||||||
|
|
||||||
|
char *s = grub_malloc (100 + grub_strlen (entry->title));
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_sprintf (s, "Booting '%s'", entry->title);
|
||||||
|
set_progress_message (view, s);
|
||||||
|
grub_free (s);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_fallback (grub_menu_entry_t entry, void *userdata)
|
||||||
|
{
|
||||||
|
grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
|
||||||
|
|
||||||
|
char *s = grub_malloc (100 + grub_strlen (entry->title));
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grub_sprintf (s, "Falling back to '%s'", entry->title);
|
||||||
|
set_progress_message (view, s);
|
||||||
|
grub_free (s);
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
grub_video_swap_buffers ();
|
||||||
|
if (view->double_repaint)
|
||||||
|
grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_execution_failure (void *userdata __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct grub_menu_execute_callback execute_callback =
|
||||||
|
{
|
||||||
|
.notify_booting = notify_booting,
|
||||||
|
.notify_fallback = notify_fallback,
|
||||||
|
.notify_failure = notify_execution_failure
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -969,19 +969,28 @@ static struct grub_menu_execute_callback execution_callback =
|
|||||||
static grub_err_t
|
static grub_err_t
|
||||||
show_menu (grub_menu_t menu, int nested, int autobooted)
|
show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||||
{
|
{
|
||||||
|
const char *def;
|
||||||
|
def = grub_env_get("VTOY_DEFAULT_IMAGE");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int boot_entry;
|
int boot_entry;
|
||||||
grub_menu_entry_t e;
|
grub_menu_entry_t e;
|
||||||
int auto_boot;
|
int auto_boot;
|
||||||
|
|
||||||
boot_entry = run_menu (menu, nested, &auto_boot);
|
boot_entry = run_menu (menu, nested, &auto_boot);
|
||||||
if (boot_entry < 0)
|
if (boot_entry < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
g_ventoy_last_entry = boot_entry;
|
if (auto_boot && def && grub_strcmp(def, "VTOY_EXIT") == 0) {
|
||||||
if (g_ventoy_menu_esc)
|
grub_exit();
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
if (autobooted == 0 && auto_boot == 0) {
|
||||||
|
g_ventoy_last_entry = boot_entry;
|
||||||
|
if (g_ventoy_menu_esc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
e = grub_menu_get_entry (menu, boot_entry);
|
e = grub_menu_get_entry (menu, boot_entry);
|
||||||
if (! e)
|
if (! e)
|
||||||
|
@@ -190,10 +190,17 @@ command-line or ESC to discard edits and return to the GRUB menu."),
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char szLine[128];
|
||||||
|
const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING");
|
||||||
|
if (checkret == NULL || checkret[0] != '0') {
|
||||||
|
grub_snprintf(szLine, sizeof(szLine), "%s [Unofficial Ventoy]", grub_env_get("VTOY_TEXT_MENU_VER"));
|
||||||
|
} else {
|
||||||
|
grub_snprintf(szLine, sizeof(szLine), "%s", grub_env_get("VTOY_TEXT_MENU_VER"));
|
||||||
|
}
|
||||||
|
|
||||||
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_TEXT_MENU_VER"),
|
ret += grub_print_message_indented_real(szLine, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||||
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(grub_env_get("VTOY_HOTKEY_TIP"),
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
|
#include <grub/acpi.h>
|
||||||
#include <grub/relocator.h>
|
#include <grub/relocator.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/ventoy.h>
|
#include <grub/ventoy.h>
|
||||||
@@ -55,6 +56,8 @@ int g_initrd_img_count = 0;
|
|||||||
int g_valid_initrd_count = 0;
|
int g_valid_initrd_count = 0;
|
||||||
int g_default_menu_mode = 0;
|
int g_default_menu_mode = 0;
|
||||||
int g_filt_dot_underscore_file = 0;
|
int g_filt_dot_underscore_file = 0;
|
||||||
|
int g_sort_case_sensitive = 0;
|
||||||
|
int g_tree_view_menu_style = 0;
|
||||||
static grub_file_t g_old_file;
|
static grub_file_t g_old_file;
|
||||||
static int g_ventoy_last_entry_back;
|
static int g_ventoy_last_entry_back;
|
||||||
|
|
||||||
@@ -79,6 +82,8 @@ grub_uint32_t g_ventoy_cpio_size = 0;
|
|||||||
cpio_newc_header *g_ventoy_initrd_head = NULL;
|
cpio_newc_header *g_ventoy_initrd_head = NULL;
|
||||||
grub_uint8_t *g_ventoy_runtime_buf = NULL;
|
grub_uint8_t *g_ventoy_runtime_buf = NULL;
|
||||||
|
|
||||||
|
int g_plugin_image_list = 0;
|
||||||
|
|
||||||
ventoy_grub_param *g_grub_param = NULL;
|
ventoy_grub_param *g_grub_param = NULL;
|
||||||
|
|
||||||
ventoy_guid g_ventoy_guid = VENTOY_GUID;
|
ventoy_guid g_ventoy_guid = VENTOY_GUID;
|
||||||
@@ -91,6 +96,12 @@ char *g_wimiso_path = NULL;
|
|||||||
|
|
||||||
int g_vhdboot_enable = 0;
|
int g_vhdboot_enable = 0;
|
||||||
|
|
||||||
|
grub_uint64_t g_conf_replace_offset = 0;
|
||||||
|
conf_replace *g_conf_replace_node = NULL;
|
||||||
|
grub_uint8_t *g_conf_replace_new_buf = NULL;
|
||||||
|
int g_conf_replace_new_len = 0;
|
||||||
|
int g_conf_replace_new_len_align = 0;
|
||||||
|
|
||||||
ventoy_gpt_info *g_ventoy_part_info = NULL;
|
ventoy_gpt_info *g_ventoy_part_info = NULL;
|
||||||
|
|
||||||
static char *g_tree_script_buf = NULL;
|
static char *g_tree_script_buf = NULL;
|
||||||
@@ -108,12 +119,12 @@ static ventoy_video_mode *g_video_mode_list = NULL;
|
|||||||
|
|
||||||
static const char *g_menu_class[] =
|
static const char *g_menu_class[] =
|
||||||
{
|
{
|
||||||
"vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd"
|
"vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_menu_prefix[] =
|
static const char *g_menu_prefix[] =
|
||||||
{
|
{
|
||||||
"iso", "wim", "efi", "img", "vhd"
|
"iso", "wim", "efi", "img", "vhd", "vtoy"
|
||||||
};
|
};
|
||||||
|
|
||||||
void ventoy_debug(const char *fmt, ...)
|
void ventoy_debug(const char *fmt, ...)
|
||||||
@@ -989,7 +1000,7 @@ static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int ar
|
|||||||
grub_disk_close(disk);
|
grub_disk_close(disk);
|
||||||
|
|
||||||
g_img_swap_tmp_buf[703] = 0;
|
g_img_swap_tmp_buf[703] = 0;
|
||||||
for (i = 319; i < 703; i++)
|
for (i = 318; i < 703; i++)
|
||||||
{
|
{
|
||||||
if (g_img_swap_tmp_buf[i] == 'V' &&
|
if (g_img_swap_tmp_buf[i] == 'V' &&
|
||||||
0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN))
|
0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN))
|
||||||
@@ -1015,19 +1026,65 @@ int ventoy_cmp_img(img_info *img1, img_info *img2)
|
|||||||
int c1 = 0;
|
int c1 = 0;
|
||||||
int c2 = 0;
|
int c2 = 0;
|
||||||
|
|
||||||
|
if (g_plugin_image_list)
|
||||||
|
{
|
||||||
|
return (img1->plugin_list_index - img2->plugin_list_index);
|
||||||
|
}
|
||||||
|
|
||||||
for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++)
|
for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++)
|
||||||
{
|
{
|
||||||
c1 = *s1;
|
c1 = *s1;
|
||||||
c2 = *s2;
|
c2 = *s2;
|
||||||
|
|
||||||
if (grub_islower(c1))
|
if (0 == g_sort_case_sensitive)
|
||||||
{
|
{
|
||||||
c1 = c1 - 'a' + 'A';
|
if (grub_islower(c1))
|
||||||
|
{
|
||||||
|
c1 = c1 - 'a' + 'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_islower(c2))
|
||||||
|
{
|
||||||
|
c2 = c2 - 'a' + 'A';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_islower(c2))
|
if (c1 != c2)
|
||||||
{
|
{
|
||||||
c2 = c2 - 'a' + 'A';
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (c1 - c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2)
|
||||||
|
{
|
||||||
|
char *s1, *s2;
|
||||||
|
int c1 = 0;
|
||||||
|
int c2 = 0;
|
||||||
|
|
||||||
|
if (g_plugin_image_list)
|
||||||
|
{
|
||||||
|
return (node1->plugin_list_index - node2->plugin_list_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s1 = node1->dir, s2 = node2->dir; *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)
|
if (c1 != c2)
|
||||||
@@ -1096,6 +1153,7 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
int ignore = 0;
|
int ignore = 0;
|
||||||
|
int index = 0;
|
||||||
grub_size_t len;
|
grub_size_t len;
|
||||||
img_info *img;
|
img_info *img;
|
||||||
img_info *tail;
|
img_info *tail;
|
||||||
@@ -1123,9 +1181,21 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_plugin_image_list)
|
||||||
|
{
|
||||||
|
grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename);
|
||||||
|
index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf);
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_node = grub_zalloc(sizeof(img_iterator_node));
|
new_node = grub_zalloc(sizeof(img_iterator_node));
|
||||||
if (new_node)
|
if (new_node)
|
||||||
{
|
{
|
||||||
|
new_node->plugin_list_index = index;
|
||||||
new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename);
|
new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename);
|
||||||
|
|
||||||
g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore);
|
g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore);
|
||||||
@@ -1159,7 +1229,7 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug("Find a file %s\n", filename);
|
debug("Find a file %s\n", filename);
|
||||||
if (len <= 4)
|
if (len < 4)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1173,7 +1243,7 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
type = img_type_wim;
|
type = img_type_wim;
|
||||||
}
|
}
|
||||||
else if (g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") ||
|
else if (g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") ||
|
||||||
0 == grub_strcasecmp(filename + len - 5, ".vhdx")))
|
(len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx"))))
|
||||||
{
|
{
|
||||||
type = img_type_vhd;
|
type = img_type_vhd;
|
||||||
}
|
}
|
||||||
@@ -1195,6 +1265,10 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
}
|
}
|
||||||
type = img_type_img;
|
type = img_type_img;
|
||||||
}
|
}
|
||||||
|
else if (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy"))
|
||||||
|
{
|
||||||
|
type = img_type_vtoy;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1204,11 +1278,23 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_plugin_image_list)
|
||||||
|
{
|
||||||
|
grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename);
|
||||||
|
index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf);
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img = grub_zalloc(sizeof(img_info));
|
img = grub_zalloc(sizeof(img_info));
|
||||||
if (img)
|
if (img)
|
||||||
{
|
{
|
||||||
img->type = type;
|
img->type = type;
|
||||||
|
img->plugin_list_index = index;
|
||||||
grub_snprintf(img->name, sizeof(img->name), "%s", filename);
|
grub_snprintf(img->name, sizeof(img->name), "%s", filename);
|
||||||
|
|
||||||
for (i = 0; i < (int)len; i++)
|
for (i = 0; i < (int)len; i++)
|
||||||
@@ -1367,10 +1453,10 @@ static img_info * ventoy_get_min_iso(img_iterator_node *node)
|
|||||||
{
|
{
|
||||||
img_info *minimg = NULL;
|
img_info *minimg = NULL;
|
||||||
img_info *img = (img_info *)(node->firstiso);
|
img_info *img = (img_info *)(node->firstiso);
|
||||||
|
|
||||||
while (img && (img_iterator_node *)(img->parent) == node)
|
while (img && (img_iterator_node *)(img->parent) == node)
|
||||||
{
|
{
|
||||||
if (img->select == 0 && (NULL == minimg || grub_strcmp(img->name, minimg->name) < 0))
|
if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0))
|
||||||
{
|
{
|
||||||
minimg = img;
|
minimg = img;
|
||||||
}
|
}
|
||||||
@@ -1392,7 +1478,7 @@ static img_iterator_node * ventoy_get_min_child(img_iterator_node *node)
|
|||||||
|
|
||||||
while (child && child->parent == node)
|
while (child && child->parent == node)
|
||||||
{
|
{
|
||||||
if (child->select == 0 && (NULL == Minchild || grub_strcmp(child->dir, Minchild->dir) < 0))
|
if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0))
|
||||||
{
|
{
|
||||||
Minchild = child;
|
Minchild = child;
|
||||||
}
|
}
|
||||||
@@ -1429,10 +1515,20 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
|
|||||||
{
|
{
|
||||||
if (g_default_menu_mode == 0)
|
if (g_default_menu_mode == 0)
|
||||||
{
|
{
|
||||||
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
if (g_tree_view_menu_style == 0)
|
||||||
"menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
|
{
|
||||||
" echo 'return ...' \n"
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
"}\n", "<--");
|
"menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
|
||||||
|
" echo 'return ...' \n"
|
||||||
|
"}\n", "<--");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
|
||||||
|
" echo '%s ...' \n"
|
||||||
|
"}\n", "return");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1446,22 +1542,52 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
|
|||||||
|
|
||||||
dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir);
|
dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir);
|
||||||
if (dir_alias)
|
if (dir_alias)
|
||||||
|
{
|
||||||
|
if (g_tree_view_menu_style == 0)
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
|
||||||
|
"DIR", dir_alias, dir_class, node->dir + offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
|
||||||
|
dir_alias, dir_class, node->dir + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dir_alias = node->dir + offset;
|
||||||
|
|
||||||
|
if (g_tree_view_menu_style == 0)
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
|
||||||
|
"DIR", dir_alias, dir_class, node->dir + offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
|
||||||
|
dir_alias, dir_class, node->dir + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_tree_view_menu_style == 0)
|
||||||
{
|
{
|
||||||
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
"submenu \"%-10s %s\" --class=\"%s\" {\n",
|
"menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n "
|
||||||
"DIR", dir_alias, dir_class);
|
" echo 'return ...' \n"
|
||||||
|
"}\n", "<--");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
"submenu \"%-10s [%s]\" --class=\"%s\" {\n",
|
"menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n "
|
||||||
"DIR", node->dir + offset, dir_class);
|
" echo '%s ...' \n"
|
||||||
|
"}\n", "return");
|
||||||
}
|
}
|
||||||
|
|
||||||
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
|
||||||
"menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n "
|
|
||||||
" echo 'return ...' \n"
|
|
||||||
"}\n", "<--");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((child = ventoy_get_min_child(node)) != NULL)
|
while ((child = ventoy_get_min_child(node)) != NULL)
|
||||||
@@ -1471,15 +1597,29 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
|
|||||||
|
|
||||||
while ((img = ventoy_get_min_iso(node)) != NULL)
|
while ((img = ventoy_get_min_iso(node)) != NULL)
|
||||||
{
|
{
|
||||||
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
if (g_tree_view_menu_style == 0)
|
||||||
"menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
|
{
|
||||||
" %s_%s \n"
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
"}\n",
|
"menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
|
||||||
grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
|
" %s_%s \n"
|
||||||
img->unsupport ? "[***********] " : "",
|
"}\n",
|
||||||
img->alias ? img->alias : img->name, img->class, img->id,
|
grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
|
||||||
img->menu_prefix,
|
img->unsupport ? "[***********] " : "",
|
||||||
img->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
img->alias ? img->alias : img->name, img->class, img->id,
|
||||||
|
img->menu_prefix,
|
||||||
|
img->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
|
||||||
|
"menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
|
||||||
|
" %s_%s \n"
|
||||||
|
"}\n",
|
||||||
|
img->unsupport ? "[***********] " : "",
|
||||||
|
img->alias ? img->alias : img->name, img->class, img->id,
|
||||||
|
img->menu_prefix,
|
||||||
|
img->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node != &g_img_iterator_head)
|
if (node != &g_img_iterator_head)
|
||||||
@@ -1495,8 +1635,9 @@ int ventoy_check_device_result(int ret)
|
|||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
grub_snprintf(buf, sizeof(buf), "%d", ret);
|
grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF));
|
||||||
ventoy_set_env("VTOY_CHKDEV_RESULT_STRING", buf);
|
grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf);
|
||||||
|
grub_env_export("VTOY_CHKDEV_RESULT_STRING");
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
@@ -1504,10 +1645,10 @@ int ventoy_check_device_result(int ret)
|
|||||||
grub_printf(VTOY_WARNING"\n");
|
grub_printf(VTOY_WARNING"\n");
|
||||||
grub_printf(VTOY_WARNING"\n\n\n");
|
grub_printf(VTOY_WARNING"\n\n\n");
|
||||||
|
|
||||||
grub_printf("This is NOT a standard Ventoy device and is NOT officially supported.\n\n");
|
grub_printf("This is NOT a standard Ventoy device and is NOT supported.\n\n");
|
||||||
grub_printf("Recommend to follow the instructions in https://www.ventoy.net to use Ventoy.\n");
|
grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n");
|
||||||
|
|
||||||
grub_printf("\n\nWill continue to boot after 10 seconds ...... ");
|
grub_printf("\n\nWill exit after 10 seconds ...... ");
|
||||||
grub_refresh();
|
grub_refresh();
|
||||||
grub_sleep(10);
|
grub_sleep(10);
|
||||||
}
|
}
|
||||||
@@ -1527,29 +1668,41 @@ int ventoy_check_device(grub_device_t dev)
|
|||||||
|
|
||||||
if (dev->disk == NULL || dev->disk->partition == NULL)
|
if (dev->disk == NULL || dev->disk->partition == NULL)
|
||||||
{
|
{
|
||||||
return ventoy_check_device_result(1);
|
return ventoy_check_device_result(1 | 0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
partition = dev->disk->partition;
|
if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) ||
|
||||||
if (partition->number != 0 || partition->start != 2048)
|
0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) ||
|
||||||
|
0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_64", dev->disk->name))
|
||||||
{
|
{
|
||||||
return ventoy_check_device_result(2);
|
return ventoy_check_device_result(2 | 0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = partition->start + partition->len;
|
|
||||||
|
|
||||||
/* We must have partition 2 */
|
/* We must have partition 2 */
|
||||||
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name);
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name);
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
return ventoy_check_device_result(3);
|
return ventoy_check_device_result(3 | 0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL == grub_strstr(file->fs->name, "fat"))
|
||||||
|
{
|
||||||
|
grub_file_close(file);
|
||||||
|
return ventoy_check_device_result(4 | 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
partition = dev->disk->partition;
|
||||||
|
if (partition->number != 0 || partition->start != 2048)
|
||||||
|
{
|
||||||
|
return ventoy_check_device_result(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = partition->start + partition->len;
|
||||||
partition = file->device->disk->partition;
|
partition = file->device->disk->partition;
|
||||||
if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start))
|
if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start))
|
||||||
{
|
{
|
||||||
grub_file_close(file);
|
grub_file_close(file);
|
||||||
return ventoy_check_device_result(4);
|
return ventoy_check_device_result(6);
|
||||||
}
|
}
|
||||||
grub_file_close(file);
|
grub_file_close(file);
|
||||||
|
|
||||||
@@ -1557,27 +1710,100 @@ int ventoy_check_device(grub_device_t dev)
|
|||||||
dev2 = grub_device_open(devname);
|
dev2 = grub_device_open(devname);
|
||||||
if (!dev2)
|
if (!dev2)
|
||||||
{
|
{
|
||||||
return ventoy_check_device_result(5);
|
return ventoy_check_device_result(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs = grub_fs_probe(dev2);
|
fs = grub_fs_probe(dev2);
|
||||||
if (!fs)
|
if (!fs)
|
||||||
{
|
{
|
||||||
grub_device_close(dev2);
|
grub_device_close(dev2);
|
||||||
return ventoy_check_device_result(6);
|
return ventoy_check_device_result(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs->fs_label(dev2, &label);
|
fs->fs_label(dev2, &label);
|
||||||
if ((!label) || grub_strncmp("VTOYEFI", label, 7))
|
if ((!label) || grub_strncmp("VTOYEFI", label, 7))
|
||||||
{
|
{
|
||||||
grub_device_close(dev2);
|
grub_device_close(dev2);
|
||||||
return ventoy_check_device_result(7);
|
return ventoy_check_device_result(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_device_close(dev2);
|
grub_device_close(dev2);
|
||||||
return ventoy_check_device_result(0);
|
return ventoy_check_device_result(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ventoy_set_default_menu(void)
|
||||||
|
{
|
||||||
|
int img_len = 0;
|
||||||
|
char *pos = NULL;
|
||||||
|
char *end = NULL;
|
||||||
|
char *def = NULL;
|
||||||
|
const char *strdata = NULL;
|
||||||
|
img_info *cur = NULL;
|
||||||
|
img_info *default_node = NULL;
|
||||||
|
const char *default_image = NULL;
|
||||||
|
|
||||||
|
default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE");
|
||||||
|
if (default_image && default_image[0] == '/')
|
||||||
|
{
|
||||||
|
img_len = grub_strlen(default_image);
|
||||||
|
|
||||||
|
for (cur = g_ventoy_img_list; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0)
|
||||||
|
{
|
||||||
|
default_node = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!default_node)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == g_default_menu_mode)
|
||||||
|
{
|
||||||
|
vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
def = grub_strdup(default_image);
|
||||||
|
if (!def)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\'');
|
||||||
|
|
||||||
|
strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
|
||||||
|
if (strdata && strdata[0] == '/')
|
||||||
|
{
|
||||||
|
pos = def + grub_strlen(strdata);
|
||||||
|
if (*pos == '/')
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos = def + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((end = grub_strchr(pos, '/')) != NULL)
|
||||||
|
{
|
||||||
|
*end = 0;
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos);
|
||||||
|
pos = end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%d'\n", default_node->id);
|
||||||
|
grub_free(def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
|
static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@@ -1585,11 +1811,8 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
grub_device_t dev = NULL;
|
grub_device_t dev = NULL;
|
||||||
img_info *cur = NULL;
|
img_info *cur = NULL;
|
||||||
img_info *tail = NULL;
|
img_info *tail = NULL;
|
||||||
img_info *default_node = NULL;
|
|
||||||
const char *strdata = NULL;
|
const char *strdata = NULL;
|
||||||
char *device_name = NULL;
|
char *device_name = NULL;
|
||||||
const char *default_image = NULL;
|
|
||||||
int img_len = 0;
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
img_iterator_node *node = NULL;
|
img_iterator_node *node = NULL;
|
||||||
img_iterator_node *tmp = NULL;
|
img_iterator_node *tmp = NULL;
|
||||||
@@ -1612,6 +1835,12 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
g_filt_dot_underscore_file = 1;
|
g_filt_dot_underscore_file = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE");
|
||||||
|
if (strdata && strdata[0] == '1' && strdata[1] == 0)
|
||||||
|
{
|
||||||
|
g_sort_case_sensitive = 1;
|
||||||
|
}
|
||||||
|
|
||||||
device_name = grub_file_get_device_name(args[0]);
|
device_name = grub_file_get_device_name(args[0]);
|
||||||
if (!device_name)
|
if (!device_name)
|
||||||
{
|
{
|
||||||
@@ -1624,9 +1853,6 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure that we are running in a correct Ventoy device */
|
|
||||||
ventoy_check_device(dev);
|
|
||||||
|
|
||||||
g_enum_fs = fs = grub_fs_probe(dev);
|
g_enum_fs = fs = grub_fs_probe(dev);
|
||||||
if (!fs)
|
if (!fs)
|
||||||
{
|
{
|
||||||
@@ -1675,6 +1901,14 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node);
|
fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE");
|
||||||
|
if (strdata && strdata[0] == '1' && strdata[1] == 0)
|
||||||
|
{
|
||||||
|
g_tree_view_menu_style = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ventoy_set_default_menu();
|
||||||
|
|
||||||
for (node = &g_img_iterator_head; node; node = node->next)
|
for (node = &g_img_iterator_head; node; node = node->next)
|
||||||
{
|
{
|
||||||
ventoy_dynamic_tree_menu(node);
|
ventoy_dynamic_tree_menu(node);
|
||||||
@@ -1709,15 +1943,6 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
"}\n", "<--");
|
"}\n", "<--");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_default_menu_mode == 0)
|
|
||||||
{
|
|
||||||
default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE");
|
|
||||||
if (default_image)
|
|
||||||
{
|
|
||||||
img_len = grub_strlen(default_image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cur = g_ventoy_img_list; cur; cur = cur->next)
|
for (cur = g_ventoy_img_list; cur; cur = cur->next)
|
||||||
{
|
{
|
||||||
vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
|
vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
|
||||||
@@ -1728,21 +1953,9 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||||||
cur->alias ? cur->alias : cur->name, cur->class, cur->id,
|
cur->alias ? cur->alias : cur->name, cur->class, cur->id,
|
||||||
cur->menu_prefix,
|
cur->menu_prefix,
|
||||||
cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
||||||
|
|
||||||
if (g_default_menu_mode == 0 && default_image && default_node == NULL)
|
|
||||||
{
|
|
||||||
if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0)
|
|
||||||
{
|
|
||||||
default_node = cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (default_node)
|
g_tree_script_buf[g_tree_script_pos] = 0;
|
||||||
{
|
|
||||||
vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_script_buf[g_list_script_pos] = 0;
|
g_list_script_buf[g_list_script_pos] = 0;
|
||||||
|
|
||||||
grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count);
|
grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count);
|
||||||
@@ -1869,7 +2082,7 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg
|
|||||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid)
|
int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature)
|
||||||
{
|
{
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
@@ -1903,6 +2116,7 @@ int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid)
|
|||||||
if (disk)
|
if (disk)
|
||||||
{
|
{
|
||||||
grub_disk_read(disk, 0, 0x180, 16, guid);
|
grub_disk_read(disk, 0, 0x180, 16, guid);
|
||||||
|
grub_disk_read(disk, 0, 0x1b8, 4, signature);
|
||||||
grub_disk_close(disk);
|
grub_disk_close(disk);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1999,7 +2213,7 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
|
|||||||
|
|
||||||
grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos);
|
grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos);
|
||||||
|
|
||||||
ventoy_get_disk_guid(file->name, param->vtoy_disk_guid);
|
ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature);
|
||||||
|
|
||||||
param->vtoy_img_size = file->size;
|
param->vtoy_img_size = file->size;
|
||||||
|
|
||||||
@@ -2112,7 +2326,10 @@ int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, gr
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = (int)grub_strlen(file->name);
|
len = (int)grub_strlen(file->name);
|
||||||
if (grub_strncasecmp(file->name + len - 4, ".img", 4) == 0)
|
if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) ||
|
||||||
|
(len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) ||
|
||||||
|
(len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) ||
|
||||||
|
(len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0))
|
||||||
{
|
{
|
||||||
for (i = 0; i < chunklist->cur_chunk; i++)
|
for (i = 0; i < chunklist->cur_chunk; i++)
|
||||||
{
|
{
|
||||||
@@ -2150,11 +2367,20 @@ static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, ch
|
|||||||
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
|
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_conf_replace_node = NULL;
|
||||||
|
g_conf_replace_offset = 0;
|
||||||
|
|
||||||
if (g_img_chunk_list.chunk)
|
if (g_img_chunk_list.chunk)
|
||||||
{
|
{
|
||||||
grub_free(g_img_chunk_list.chunk);
|
grub_free(g_img_chunk_list.chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max)
|
||||||
|
{
|
||||||
|
grub_file_close(file);
|
||||||
|
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name);
|
||||||
|
}
|
||||||
|
|
||||||
/* get image chunk data */
|
/* get image chunk data */
|
||||||
grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list));
|
grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list));
|
||||||
g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
|
g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
|
||||||
@@ -2182,6 +2408,75 @@ static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, ch
|
|||||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
{
|
||||||
|
grub_uint64_t offset = 0;
|
||||||
|
grub_uint32_t align = 0;
|
||||||
|
grub_file_t file = NULL;
|
||||||
|
conf_replace *node = NULL;
|
||||||
|
|
||||||
|
(void)ctxt;
|
||||||
|
(void)argc;
|
||||||
|
(void)args;
|
||||||
|
|
||||||
|
debug("select conf replace argc:%d\n", argc);
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = ventoy_plugin_find_conf_replace(args[1]);
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
debug("Conf replace not found for %s\n", args[1]);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Find conf replace for %s\n", args[1]);
|
||||||
|
|
||||||
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
debug("<(loop)%s> NOT exist\n", node->orgconf);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = grub_iso9660_get_last_file_dirent_pos(file);
|
||||||
|
grub_file_close(file);
|
||||||
|
|
||||||
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
debug("New config file <%s%s> NOT exist\n", args[0], node->newconf);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
align = ((int)file->size + 2047) / 2048 * 2048;
|
||||||
|
|
||||||
|
if (align > vtoy_max_replace_file_size)
|
||||||
|
{
|
||||||
|
debug("New config file <%s%s> too big\n", args[0], node->newconf);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_file_read(file, g_conf_replace_new_buf, file->size);
|
||||||
|
g_conf_replace_new_len = (int)file->size;
|
||||||
|
g_conf_replace_new_len_align = align;
|
||||||
|
|
||||||
|
g_conf_replace_node = node;
|
||||||
|
g_conf_replace_offset = offset + 2;
|
||||||
|
|
||||||
|
debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len);
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
grub_file_close(file);
|
||||||
|
}
|
||||||
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
|
static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -2511,7 +2806,7 @@ static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc,
|
|||||||
|
|
||||||
while (cur)
|
while (cur)
|
||||||
{
|
{
|
||||||
grub_printf("path:<%s> id=%d\n", cur->path, cur->id);
|
grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index);
|
||||||
grub_printf("name:<%s>\n\n", cur->name);
|
grub_printf("name:<%s>\n\n", cur->name);
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
@@ -2977,6 +3272,119 @@ static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int arg
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int buflen;
|
||||||
|
int datalen;
|
||||||
|
int loclen;
|
||||||
|
int img_chunk_num;
|
||||||
|
int image_sector_size;
|
||||||
|
char cmd[64];
|
||||||
|
ventoy_chain_head *chain;
|
||||||
|
ventoy_img_chunk *chunk;
|
||||||
|
ventoy_os_param *osparam;
|
||||||
|
ventoy_image_location *location;
|
||||||
|
ventoy_image_disk_region *region;
|
||||||
|
struct grub_acpi_table_header *acpi;
|
||||||
|
|
||||||
|
(void)ctxt;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]);
|
||||||
|
|
||||||
|
chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16);
|
||||||
|
if (!chain)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_sector_size = (int)grub_strtol(args[1], NULL, 10);
|
||||||
|
|
||||||
|
if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16))
|
||||||
|
{
|
||||||
|
debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img_chunk_num = chain->img_chunk_num;
|
||||||
|
|
||||||
|
loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
|
||||||
|
datalen = sizeof(ventoy_os_param) + loclen;
|
||||||
|
|
||||||
|
buflen = sizeof(struct grub_acpi_table_header) + datalen;
|
||||||
|
acpi = grub_zalloc(buflen);
|
||||||
|
if (!acpi)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step1: Fill acpi table header */
|
||||||
|
grub_memcpy(acpi->signature, "VTOY", 4);
|
||||||
|
acpi->length = buflen;
|
||||||
|
acpi->revision = 1;
|
||||||
|
grub_memcpy(acpi->oemid, "VENTOY", 6);
|
||||||
|
grub_memcpy(acpi->oemtable, "OSPARAMS", 8);
|
||||||
|
acpi->oemrev = 1;
|
||||||
|
acpi->creator_id[0] = 1;
|
||||||
|
acpi->creator_rev = 1;
|
||||||
|
|
||||||
|
/* Step2: Fill data */
|
||||||
|
osparam = (ventoy_os_param *)(acpi + 1);
|
||||||
|
grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param));
|
||||||
|
osparam->vtoy_img_location_addr = 0;
|
||||||
|
osparam->vtoy_img_location_len = loclen;
|
||||||
|
osparam->chksum = 0;
|
||||||
|
osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param));
|
||||||
|
|
||||||
|
location = (ventoy_image_location *)(osparam + 1);
|
||||||
|
grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid));
|
||||||
|
location->image_sector_size = image_sector_size;
|
||||||
|
location->disk_sector_size = chain->disk_sector_size;
|
||||||
|
location->region_count = img_chunk_num;
|
||||||
|
|
||||||
|
region = location->regions;
|
||||||
|
chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
|
||||||
|
if (512 == image_sector_size)
|
||||||
|
{
|
||||||
|
for (i = 0; i < img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
|
||||||
|
region->image_start_sector = chunk->img_start_sector * 4;
|
||||||
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
||||||
|
region->image_start_sector = chunk->img_start_sector;
|
||||||
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step3: Fill acpi checksum */
|
||||||
|
acpi->checksum = 0;
|
||||||
|
acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length);
|
||||||
|
|
||||||
|
/* load acpi table */
|
||||||
|
grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length);
|
||||||
|
grub_script_execute_sourcecode(cmd);
|
||||||
|
|
||||||
|
grub_free(acpi);
|
||||||
|
|
||||||
|
VENTOY_CMD_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
|
static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
(void)ctxt;
|
(void)ctxt;
|
||||||
@@ -3081,7 +3489,10 @@ end:
|
|||||||
|
|
||||||
static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args)
|
static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
|
char name[64];
|
||||||
|
int ret;
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
|
grub_device_t dev;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)ctxt;
|
(void)ctxt;
|
||||||
@@ -3101,7 +3512,21 @@ static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int arg
|
|||||||
|
|
||||||
grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info);
|
grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info);
|
||||||
grub_disk_close(disk);
|
grub_disk_close(disk);
|
||||||
|
|
||||||
|
grub_snprintf(name, sizeof(name), "%s,1", args[0]);
|
||||||
|
dev = grub_device_open(name);
|
||||||
|
if (dev)
|
||||||
|
{
|
||||||
|
/* make sure that we are running in a correct Ventoy device */
|
||||||
|
ret = ventoy_check_device(dev);
|
||||||
|
grub_device_close(dev);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
grub_exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3481,6 +3906,7 @@ static int ventoy_env_init(void)
|
|||||||
g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN);
|
g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN);
|
||||||
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
||||||
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
||||||
|
g_conf_replace_new_buf = grub_malloc(vtoy_max_replace_file_size);
|
||||||
|
|
||||||
ventoy_filt_register(0, ventoy_wrapper_open);
|
ventoy_filt_register(0, ventoy_wrapper_open);
|
||||||
|
|
||||||
@@ -3492,6 +3918,8 @@ static int ventoy_env_init(void)
|
|||||||
g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf;
|
g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf;
|
||||||
grub_snprintf(buf, sizeof(buf), "%p", g_grub_param);
|
grub_snprintf(buf, sizeof(buf), "%p", g_grub_param);
|
||||||
grub_env_set("env_param", buf);
|
grub_env_set("env_param", buf);
|
||||||
|
grub_env_set("ventoy_env_param", buf);
|
||||||
|
grub_env_export("ventoy_env_param");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3517,6 +3945,8 @@ static cmd_para ventoy_cmds[] =
|
|||||||
{ "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL },
|
{ "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL },
|
||||||
{ "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL },
|
{ "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL },
|
||||||
{ "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL },
|
{ "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL },
|
||||||
|
{ "vt_raw_chain_data", ventoy_cmd_raw_chain_data, 0, NULL, "", "", NULL },
|
||||||
|
{ "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type, 0, NULL, "", "", NULL },
|
||||||
|
|
||||||
{ "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL },
|
{ "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL },
|
||||||
{ "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },
|
{ "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },
|
||||||
@@ -3545,6 +3975,7 @@ static cmd_para ventoy_cmds[] =
|
|||||||
{ "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
|
{ "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
|
||||||
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
|
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
|
||||||
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
|
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
|
||||||
|
{ "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL },
|
||||||
|
|
||||||
{ "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
|
{ "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
|
||||||
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
|
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
|
||||||
@@ -3597,6 +4028,7 @@ static cmd_para ventoy_cmds[] =
|
|||||||
|
|
||||||
{ "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL },
|
{ "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL },
|
||||||
{ "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL },
|
{ "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL },
|
||||||
|
{ "vt_acpi_param", ventoy_cmd_acpi_param, 0, NULL, "", "", NULL },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3608,7 +4040,7 @@ GRUB_MOD_INIT(ventoy)
|
|||||||
cmd_para *cur = NULL;
|
cmd_para *cur = NULL;
|
||||||
|
|
||||||
ventoy_env_init();
|
ventoy_env_init();
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++)
|
for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++)
|
||||||
{
|
{
|
||||||
cur = ventoy_cmds + i;
|
cur = ventoy_cmds + i;
|
||||||
|
@@ -28,7 +28,8 @@
|
|||||||
#define VTOY_FILT_MIN_FILE_SIZE 32768
|
#define VTOY_FILT_MIN_FILE_SIZE 32768
|
||||||
|
|
||||||
#define VTOY_SIZE_1GB 1073741824
|
#define VTOY_SIZE_1GB 1073741824
|
||||||
#define VTOY_SIZE_512KB (512 * 1024)
|
#define VTOY_SIZE_1MB (1024 * 1024)
|
||||||
|
#define VTOY_SIZE_512KB (512 * 1024)
|
||||||
#define VTOY_SIZE_1KB 1024
|
#define VTOY_SIZE_1KB 1024
|
||||||
|
|
||||||
#define JSON_SUCCESS 0
|
#define JSON_SUCCESS 0
|
||||||
@@ -51,6 +52,12 @@
|
|||||||
|
|
||||||
#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
#define VTOY_DUAL_MODE_SUFFIX "uefi"
|
||||||
|
#else
|
||||||
|
#define VTOY_DUAL_MODE_SUFFIX "legacy"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct ventoy_initrd_ctx
|
typedef struct ventoy_initrd_ctx
|
||||||
{
|
{
|
||||||
const char *path_prefix;
|
const char *path_prefix;
|
||||||
@@ -152,11 +159,12 @@ typedef struct ventoy_iso9660_vd
|
|||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
#define img_type_iso 0
|
#define img_type_iso 0
|
||||||
#define img_type_wim 1
|
#define img_type_wim 1
|
||||||
#define img_type_efi 2
|
#define img_type_efi 2
|
||||||
#define img_type_img 3
|
#define img_type_img 3
|
||||||
#define img_type_vhd 4
|
#define img_type_vhd 4
|
||||||
|
#define img_type_vtoy 5
|
||||||
|
|
||||||
typedef struct img_info
|
typedef struct img_info
|
||||||
{
|
{
|
||||||
@@ -170,6 +178,7 @@ typedef struct img_info
|
|||||||
|
|
||||||
int id;
|
int id;
|
||||||
int type;
|
int type;
|
||||||
|
int plugin_list_index;
|
||||||
grub_uint64_t size;
|
grub_uint64_t size;
|
||||||
int select;
|
int select;
|
||||||
int unsupport;
|
int unsupport;
|
||||||
@@ -190,6 +199,8 @@ typedef struct img_iterator_node
|
|||||||
int done;
|
int done;
|
||||||
int select;
|
int select;
|
||||||
|
|
||||||
|
int plugin_list_index;
|
||||||
|
|
||||||
struct img_iterator_node *parent;
|
struct img_iterator_node *parent;
|
||||||
struct img_iterator_node *firstchild;
|
struct img_iterator_node *firstchild;
|
||||||
|
|
||||||
@@ -656,6 +667,41 @@ typedef struct ventoy_gpt_info
|
|||||||
ventoy_gpt_head Head;
|
ventoy_gpt_head Head;
|
||||||
ventoy_gpt_part_tbl PartTbl[128];
|
ventoy_gpt_part_tbl PartTbl[128];
|
||||||
}ventoy_gpt_info;
|
}ventoy_gpt_info;
|
||||||
|
|
||||||
|
typedef struct vhd_footer_t
|
||||||
|
{
|
||||||
|
char cookie[8]; // Cookie
|
||||||
|
grub_uint32_t features; // Features
|
||||||
|
grub_uint32_t ffversion; // File format version
|
||||||
|
grub_uint32_t dataoffset; // Data offset
|
||||||
|
grub_uint32_t timestamp; // Timestamp
|
||||||
|
grub_uint32_t creatorapp; // Creator application
|
||||||
|
grub_uint32_t creatorver; // Creator version
|
||||||
|
grub_uint32_t creatorhos; // Creator host OS
|
||||||
|
grub_uint32_t origsize; // Original size
|
||||||
|
grub_uint32_t currsize; // Current size
|
||||||
|
grub_uint32_t diskgeom; // Disk geometry
|
||||||
|
grub_uint32_t disktype; // Disk type
|
||||||
|
grub_uint32_t checksum; // Checksum
|
||||||
|
grub_uint8_t uniqueid[16]; // Unique ID
|
||||||
|
grub_uint8_t savedst; // Saved state
|
||||||
|
}vhd_footer_t;
|
||||||
|
|
||||||
|
#define VDI_IMAGE_FILE_INFO "<<< Oracle VM VirtualBox Disk Image >>>\n"
|
||||||
|
|
||||||
|
/** Image signature. */
|
||||||
|
#define VDI_IMAGE_SIGNATURE (0xbeda107f)
|
||||||
|
|
||||||
|
typedef struct VDIPREHEADER
|
||||||
|
{
|
||||||
|
/** Just text info about image type, for eyes only. */
|
||||||
|
char szFileInfo[64];
|
||||||
|
/** The image signature (VDI_IMAGE_SIGNATURE). */
|
||||||
|
grub_uint32_t u32Signature;
|
||||||
|
/** The image version (VDI_IMAGE_VERSION). */
|
||||||
|
grub_uint32_t u32Version;
|
||||||
|
} VDIPREHEADER, *PVDIPREHEADER;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
typedef struct ventoy_video_mode
|
typedef struct ventoy_video_mode
|
||||||
@@ -724,6 +770,17 @@ typedef struct menu_class
|
|||||||
struct menu_class *next;
|
struct menu_class *next;
|
||||||
}menu_class;
|
}menu_class;
|
||||||
|
|
||||||
|
#define vtoy_max_replace_file_size (2 * 1024 * 1024)
|
||||||
|
typedef struct conf_replace
|
||||||
|
{
|
||||||
|
int pathlen;
|
||||||
|
char isopath[256];
|
||||||
|
char orgconf[256];
|
||||||
|
char newconf[256];
|
||||||
|
|
||||||
|
struct conf_replace *next;
|
||||||
|
}conf_replace;
|
||||||
|
|
||||||
typedef struct injection_config
|
typedef struct injection_config
|
||||||
{
|
{
|
||||||
int pathlen;
|
int pathlen;
|
||||||
@@ -741,6 +798,14 @@ typedef struct auto_memdisk
|
|||||||
struct auto_memdisk *next;
|
struct auto_memdisk *next;
|
||||||
}auto_memdisk;
|
}auto_memdisk;
|
||||||
|
|
||||||
|
typedef struct image_list
|
||||||
|
{
|
||||||
|
int pathlen;
|
||||||
|
char isopath[256];
|
||||||
|
|
||||||
|
struct image_list *next;
|
||||||
|
}image_list;
|
||||||
|
|
||||||
extern int g_ventoy_menu_esc;
|
extern int g_ventoy_menu_esc;
|
||||||
extern int g_ventoy_suppress_esc;
|
extern int g_ventoy_suppress_esc;
|
||||||
extern int g_ventoy_last_entry;
|
extern int g_ventoy_last_entry;
|
||||||
@@ -750,8 +815,13 @@ extern int g_ventoy_iso_uefi_drv;
|
|||||||
extern int g_ventoy_case_insensitive;
|
extern int g_ventoy_case_insensitive;
|
||||||
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_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 conf_replace *g_conf_replace_node;
|
||||||
|
extern grub_uint8_t *g_conf_replace_new_buf;
|
||||||
|
extern int g_conf_replace_new_len;
|
||||||
|
extern int g_conf_replace_new_len_align;
|
||||||
|
|
||||||
#define ventoy_unix_fill_virt(new_data, new_len) \
|
#define ventoy_unix_fill_virt(new_data, new_len) \
|
||||||
{ \
|
{ \
|
||||||
@@ -783,6 +853,8 @@ 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);
|
||||||
const char * ventoy_plugin_get_menu_class(int type, const char *name);
|
const char * ventoy_plugin_get_menu_class(int type, const char *name);
|
||||||
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);
|
||||||
|
conf_replace * ventoy_plugin_find_conf_replace(const char *iso);
|
||||||
int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
|
int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
|
||||||
int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
|
int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
|
||||||
void ventoy_plugin_dump_persistence(void);
|
void ventoy_plugin_dump_persistence(void);
|
||||||
@@ -792,7 +864,7 @@ grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, ch
|
|||||||
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_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);
|
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_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_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);
|
||||||
@@ -803,6 +875,8 @@ int ventoy_check_device(grub_device_t dev);
|
|||||||
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid);
|
void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid);
|
||||||
grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
|
grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
|
grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||||
|
|
||||||
#endif /* __VENTOY_DEF_H__ */
|
#endif /* __VENTOY_DEF_H__ */
|
||||||
|
|
||||||
|
@@ -333,6 +333,7 @@ end:
|
|||||||
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 dollar = 0;
|
||||||
grub_file_t file = NULL;
|
grub_file_t file = NULL;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
char *start = NULL;
|
char *start = NULL;
|
||||||
@@ -388,13 +389,18 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dollar = 0;
|
||||||
for (i = 0; i < 255 && (0 == ventoy_is_word_end(*start)); i++)
|
for (i = 0; i < 255 && (0 == ventoy_is_word_end(*start)); i++)
|
||||||
{
|
{
|
||||||
img->name[i] = *start++;
|
img->name[i] = *start++;
|
||||||
|
if (img->name[i] == '$')
|
||||||
|
{
|
||||||
|
dollar = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
|
if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
|
||||||
{
|
{
|
||||||
grub_free(img);
|
grub_free(img);
|
||||||
}
|
}
|
||||||
@@ -625,9 +631,30 @@ int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, co
|
|||||||
return headlen;
|
return headlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_uint32_t ventoy_linux_get_virt_chunk_count(void)
|
||||||
|
{
|
||||||
|
grub_uint32_t count = g_valid_initrd_count;
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_uint32_t ventoy_linux_get_virt_chunk_size(void)
|
static grub_uint32_t ventoy_linux_get_virt_chunk_size(void)
|
||||||
{
|
{
|
||||||
return (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count;
|
grub_uint32_t size;
|
||||||
|
|
||||||
|
size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count;
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
|
static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
|
||||||
@@ -646,7 +673,7 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_
|
|||||||
sector = (isosize + 2047) / 2048;
|
sector = (isosize + 2047) / 2048;
|
||||||
cpio_secs = g_ventoy_cpio_size / 2048;
|
cpio_secs = g_ventoy_cpio_size / 2048;
|
||||||
|
|
||||||
offset = g_valid_initrd_count * sizeof(ventoy_virt_chunk);
|
offset = ventoy_linux_get_virt_chunk_count() * sizeof(ventoy_virt_chunk);
|
||||||
cur = (ventoy_virt_chunk *)override;
|
cur = (ventoy_virt_chunk *)override;
|
||||||
|
|
||||||
for (node = g_initrd_img_list; node; node = node->next)
|
for (node = g_initrd_img_list; node; node = node->next)
|
||||||
@@ -682,12 +709,51 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_
|
|||||||
cur++;
|
cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
cpio_secs = g_conf_replace_new_len_align / 2048;
|
||||||
|
|
||||||
|
cur->mem_sector_start = sector;
|
||||||
|
cur->mem_sector_end = cur->mem_sector_start + cpio_secs;
|
||||||
|
cur->mem_sector_offset = offset;
|
||||||
|
cur->remap_sector_start = 0;
|
||||||
|
cur->remap_sector_end = 0;
|
||||||
|
cur->org_sector_start = 0;
|
||||||
|
|
||||||
|
grub_memcpy(override + offset, g_conf_replace_new_buf, g_conf_replace_new_len);
|
||||||
|
|
||||||
|
chain->virt_img_size_in_bytes += g_conf_replace_new_len_align;
|
||||||
|
|
||||||
|
offset += g_conf_replace_new_len_align;
|
||||||
|
sector += cpio_secs;
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_uint32_t ventoy_linux_get_override_chunk_count(void)
|
||||||
|
{
|
||||||
|
grub_uint32_t count = g_valid_initrd_count;
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
|
static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
|
||||||
{
|
{
|
||||||
return sizeof(ventoy_override_chunk) * g_valid_initrd_count;
|
int count = g_valid_initrd_count;
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof(ventoy_override_chunk) * count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override)
|
static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override)
|
||||||
@@ -697,6 +763,8 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
|
|||||||
grub_uint32_t newlen;
|
grub_uint32_t newlen;
|
||||||
grub_uint64_t sector;
|
grub_uint64_t sector;
|
||||||
ventoy_override_chunk *cur;
|
ventoy_override_chunk *cur;
|
||||||
|
ventoy_iso9660_override *dirent;
|
||||||
|
ventoy_udf_override *udf;
|
||||||
|
|
||||||
sector = (isosize + 2047) / 2048;
|
sector = (isosize + 2047) / 2048;
|
||||||
|
|
||||||
@@ -712,12 +780,12 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
|
|||||||
mod = newlen % 4;
|
mod = newlen % 4;
|
||||||
if (mod > 0)
|
if (mod > 0)
|
||||||
{
|
{
|
||||||
newlen += 4 - mod;
|
newlen += 4 - mod; /* cpio must align with 4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->iso_type == 0)
|
if (node->iso_type == 0)
|
||||||
{
|
{
|
||||||
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)node->override_data;
|
dirent = (ventoy_iso9660_override *)node->override_data;
|
||||||
|
|
||||||
node->override_length = sizeof(ventoy_iso9660_override);
|
node->override_length = sizeof(ventoy_iso9660_override);
|
||||||
dirent->first_sector = (grub_uint32_t)sector;
|
dirent->first_sector = (grub_uint32_t)sector;
|
||||||
@@ -729,7 +797,7 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ventoy_udf_override *udf = (ventoy_udf_override *)node->override_data;
|
udf = (ventoy_udf_override *)node->override_data;
|
||||||
|
|
||||||
node->override_length = sizeof(ventoy_udf_override);
|
node->override_length = sizeof(ventoy_udf_override);
|
||||||
udf->length = newlen;
|
udf->length = newlen;
|
||||||
@@ -744,6 +812,23 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
|
|||||||
cur++;
|
cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_conf_replace_offset > 0)
|
||||||
|
{
|
||||||
|
cur->img_offset = g_conf_replace_offset;
|
||||||
|
cur->override_size = sizeof(ventoy_iso9660_override);
|
||||||
|
|
||||||
|
newlen = (grub_uint32_t)(g_conf_replace_new_len);
|
||||||
|
|
||||||
|
dirent = (ventoy_iso9660_override *)cur->override_data;
|
||||||
|
dirent->first_sector = (grub_uint32_t)sector;
|
||||||
|
dirent->size = newlen;
|
||||||
|
dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
|
||||||
|
dirent->size_be = grub_swap_bytes32(dirent->size);
|
||||||
|
|
||||||
|
sector += (dirent->size + 2047) / 2048;
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,7 +1326,9 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
|
|||||||
grub_uint64_t isosize = 0;
|
grub_uint64_t isosize = 0;
|
||||||
grub_uint32_t boot_catlog = 0;
|
grub_uint32_t boot_catlog = 0;
|
||||||
grub_uint32_t img_chunk_size = 0;
|
grub_uint32_t img_chunk_size = 0;
|
||||||
|
grub_uint32_t override_count = 0;
|
||||||
grub_uint32_t override_size = 0;
|
grub_uint32_t override_size = 0;
|
||||||
|
grub_uint32_t virt_chunk_count = 0;
|
||||||
grub_uint32_t virt_chunk_size = 0;
|
grub_uint32_t virt_chunk_size = 0;
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
grub_disk_t disk;
|
grub_disk_t disk;
|
||||||
@@ -1294,6 +1381,9 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
override_count = ventoy_linux_get_override_chunk_count();
|
||||||
|
virt_chunk_count = ventoy_linux_get_virt_chunk_count();
|
||||||
|
|
||||||
if (ventoy_compatible)
|
if (ventoy_compatible)
|
||||||
{
|
{
|
||||||
@@ -1360,20 +1450,21 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_valid_initrd_count == 0)
|
/* part 4: override chunk */
|
||||||
|
if (override_count > 0)
|
||||||
{
|
{
|
||||||
return 0;
|
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
|
||||||
|
chain->override_chunk_num = override_count;
|
||||||
|
ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* part 4: override chunk */
|
|
||||||
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
|
|
||||||
chain->override_chunk_num = g_valid_initrd_count;
|
|
||||||
ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
|
|
||||||
|
|
||||||
/* part 5: virt chunk */
|
/* part 5: virt chunk */
|
||||||
chain->virt_chunk_offset = chain->override_chunk_offset + override_size;
|
if (virt_chunk_count > 0)
|
||||||
chain->virt_chunk_num = g_valid_initrd_count;
|
{
|
||||||
ventoy_linux_fill_virt_data(isosize, chain);
|
chain->virt_chunk_offset = chain->override_chunk_offset + override_size;
|
||||||
|
chain->virt_chunk_num = virt_chunk_count;
|
||||||
|
ventoy_linux_fill_virt_data(isosize, chain);
|
||||||
|
}
|
||||||
|
|
||||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
@@ -46,6 +46,8 @@ static menu_alias *g_menu_alias_head = NULL;
|
|||||||
static menu_class *g_menu_class_head = NULL;
|
static menu_class *g_menu_class_head = NULL;
|
||||||
static injection_config *g_injection_head = NULL;
|
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 conf_replace *g_conf_replace_head = NULL;
|
||||||
|
|
||||||
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
|
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
|
||||||
{
|
{
|
||||||
@@ -68,7 +70,15 @@ static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
|
|||||||
pChild = pNode->pstChild;
|
pChild = pNode->pstChild;
|
||||||
if (pChild->enDataType == JSON_TYPE_STRING)
|
if (pChild->enDataType == JSON_TYPE_STRING)
|
||||||
{
|
{
|
||||||
grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
|
if (grub_strcmp(pChild->pcName, "VTOY_DEFAULT_IMAGE") == 0)
|
||||||
|
{
|
||||||
|
grub_printf("%s: %s [%s]\n", pChild->pcName, pChild->unData.pcStrVal,
|
||||||
|
ventoy_check_file_exist("%s%s", isodisk, pChild->unData.pcStrVal) ? "OK" : "NOT EXIST");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1011,6 +1021,146 @@ static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk)
|
||||||
|
{
|
||||||
|
const char *isof = NULL;
|
||||||
|
const char *orgf = NULL;
|
||||||
|
const char *newf = NULL;
|
||||||
|
VTOY_JSON *pNode = NULL;
|
||||||
|
conf_replace *tail = NULL;
|
||||||
|
conf_replace *node = NULL;
|
||||||
|
conf_replace *next = NULL;
|
||||||
|
|
||||||
|
(void)isodisk;
|
||||||
|
|
||||||
|
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
debug("Not array %d\n", json->enDataType);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_conf_replace_head)
|
||||||
|
{
|
||||||
|
for (node = g_conf_replace_head; node; node = next)
|
||||||
|
{
|
||||||
|
next = node->next;
|
||||||
|
grub_free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_conf_replace_head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||||
|
{
|
||||||
|
isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
|
||||||
|
orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
|
||||||
|
newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
|
||||||
|
if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
|
||||||
|
{
|
||||||
|
node = grub_zalloc(sizeof(conf_replace));
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof);
|
||||||
|
grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf);
|
||||||
|
grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf);
|
||||||
|
|
||||||
|
if (g_conf_replace_head)
|
||||||
|
{
|
||||||
|
tail->next = node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_conf_replace_head = node;
|
||||||
|
}
|
||||||
|
tail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk)
|
||||||
|
{
|
||||||
|
const char *isof = NULL;
|
||||||
|
const char *orgf = NULL;
|
||||||
|
const char *newf = NULL;
|
||||||
|
VTOY_JSON *pNode = NULL;
|
||||||
|
grub_file_t file = NULL;
|
||||||
|
char cmd[256];
|
||||||
|
|
||||||
|
(void)isodisk;
|
||||||
|
|
||||||
|
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
grub_printf("Not array %d\n", json->enDataType);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||||
|
{
|
||||||
|
isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
|
||||||
|
orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
|
||||||
|
newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
|
||||||
|
if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
|
||||||
|
{
|
||||||
|
if (ventoy_check_file_exist("%s%s", isodisk, isof))
|
||||||
|
{
|
||||||
|
grub_printf("iso:<%s> [OK]\n", isof);
|
||||||
|
|
||||||
|
grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck %s%s", isodisk, isof);
|
||||||
|
grub_script_execute_sourcecode(cmd);
|
||||||
|
|
||||||
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
if (grub_strcmp(file->fs->name, "iso9660") == 0)
|
||||||
|
{
|
||||||
|
grub_printf("org:<%s> [OK]\n", orgf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf);
|
||||||
|
}
|
||||||
|
grub_file_close(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("org:<%s> [NOT Exist]\n", orgf);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_script_execute_sourcecode("loopback -d vtisocheck");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("iso:<%s> [NOT Exist]\n", isof);
|
||||||
|
grub_printf("org:<%s>\n", orgf);
|
||||||
|
}
|
||||||
|
|
||||||
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf);
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
if (file->size > vtoy_max_replace_file_size)
|
||||||
|
{
|
||||||
|
grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("new:<%s> [OK]\n", newf);
|
||||||
|
}
|
||||||
|
grub_file_close(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf("new:<%s> [NOT Exist]\n", newf);
|
||||||
|
}
|
||||||
|
grub_printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
|
static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
|
||||||
{
|
{
|
||||||
VTOY_JSON *pNode = NULL;
|
VTOY_JSON *pNode = NULL;
|
||||||
@@ -1088,6 +1238,89 @@ static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk)
|
||||||
|
{
|
||||||
|
VTOY_JSON *pNode = NULL;
|
||||||
|
image_list *node = NULL;
|
||||||
|
image_list *next = NULL;
|
||||||
|
image_list *tail = NULL;
|
||||||
|
|
||||||
|
(void)isodisk;
|
||||||
|
|
||||||
|
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
debug("Not array %d\n", json->enDataType);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_image_list_head)
|
||||||
|
{
|
||||||
|
for (node = g_image_list_head; node; node = next)
|
||||||
|
{
|
||||||
|
next = node->next;
|
||||||
|
grub_free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_image_list_head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_plugin_image_list = 1;
|
||||||
|
|
||||||
|
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||||
|
{
|
||||||
|
if (pNode->enDataType == JSON_TYPE_STRING)
|
||||||
|
{
|
||||||
|
node = grub_zalloc(sizeof(image_list));
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
|
||||||
|
|
||||||
|
if (g_image_list_head)
|
||||||
|
{
|
||||||
|
tail->next = node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_image_list_head = node;
|
||||||
|
}
|
||||||
|
tail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk)
|
||||||
|
{
|
||||||
|
VTOY_JSON *pNode = NULL;
|
||||||
|
|
||||||
|
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||||
|
{
|
||||||
|
grub_printf("Not array %d\n", json->enDataType);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||||
|
{
|
||||||
|
if (pNode->enDataType == JSON_TYPE_STRING)
|
||||||
|
{
|
||||||
|
grub_printf("<%s> ", pNode->unData.pcStrVal);
|
||||||
|
|
||||||
|
if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal))
|
||||||
|
{
|
||||||
|
grub_printf(" [OK]\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_printf(" [NOT EXIST]\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static plugin_entry g_plugin_entries[] =
|
static plugin_entry g_plugin_entries[] =
|
||||||
{
|
{
|
||||||
{ "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
|
{ "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
|
||||||
@@ -1098,11 +1331,14 @@ static plugin_entry g_plugin_entries[] =
|
|||||||
{ "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check },
|
{ "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check },
|
||||||
{ "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
|
{ "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
|
||||||
{ "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check },
|
{ "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check },
|
||||||
|
{ "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check },
|
||||||
|
{ "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
|
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
char key[128];
|
||||||
VTOY_JSON *cur = json;
|
VTOY_JSON *cur = json;
|
||||||
|
|
||||||
grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
|
grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk);
|
||||||
@@ -1111,7 +1347,8 @@ static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
|
for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
|
||||||
{
|
{
|
||||||
if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0)
|
grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, VTOY_DUAL_MODE_SUFFIX);
|
||||||
|
if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0 || grub_strcmp(key, cur->pcName) == 0)
|
||||||
{
|
{
|
||||||
debug("Plugin entry for %s\n", g_plugin_entries[i].key);
|
debug("Plugin entry for %s\n", g_plugin_entries[i].key);
|
||||||
g_plugin_entries[i].entryfunc(cur, isodisk);
|
g_plugin_entries[i].entryfunc(cur, isodisk);
|
||||||
@@ -1142,7 +1379,7 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
|
|||||||
}
|
}
|
||||||
|
|
||||||
debug("json configuration file size %d\n", (int)file->size);
|
debug("json configuration file size %d\n", (int)file->size);
|
||||||
|
|
||||||
buf = grub_malloc(file->size + 1);
|
buf = grub_malloc(file->size + 1);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
@@ -1165,6 +1402,9 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
|
|||||||
ret = vtoy_json_parse(json, buf);
|
ret = vtoy_json_parse(json, buf);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
|
||||||
|
grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
|
||||||
|
|
||||||
debug("Failed to parse json string %d\n", ret);
|
debug("Failed to parse json string %d\n", ret);
|
||||||
grub_free(buf);
|
grub_free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1464,11 +1704,69 @@ int ventoy_plugin_check_memdisk(const char *isopath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ventoy_plugin_get_image_list_index(int type, const char *name)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int index = 1;
|
||||||
|
image_list *node = NULL;
|
||||||
|
|
||||||
|
if (!g_image_list_head)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (int)grub_strlen(name);
|
||||||
|
|
||||||
|
for (node = g_image_list_head; node; node = node->next, index++)
|
||||||
|
{
|
||||||
|
if (vtoy_class_directory == type)
|
||||||
|
{
|
||||||
|
if (len < node->pathlen && grub_strncmp(name, node->isopath, len) == 0)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (len == node->pathlen && grub_strncmp(name, node->isopath, len) == 0)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
conf_replace *node;
|
||||||
|
|
||||||
|
if (!g_conf_replace_head)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (int)grub_strlen(iso);
|
||||||
|
|
||||||
|
for (node = g_conf_replace_head; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->pathlen == len && grub_strncmp(iso, node->isopath, len) == 0)
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
|
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
char key[128];
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
VTOY_JSON *node = NULL;
|
VTOY_JSON *node = NULL;
|
||||||
VTOY_JSON *json = NULL;
|
VTOY_JSON *json = NULL;
|
||||||
@@ -1511,9 +1809,10 @@ grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, ch
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_snprintf(key, sizeof(key), "%s_%s", args[1], VTOY_DUAL_MODE_SUFFIX);
|
||||||
for (node = json->pstChild; node; node = node->pstNext)
|
for (node = json->pstChild; node; node = node->pstNext)
|
||||||
{
|
{
|
||||||
if (grub_strcmp(node->pcName, args[1]) == 0)
|
if (grub_strcmp(node->pcName, args[1]) == 0 || grub_strcmp(node->pcName, key) == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -194,6 +194,7 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath)
|
|||||||
grub_file_t isofile;
|
grub_file_t isofile;
|
||||||
char uuid[64] = {0};
|
char uuid[64] = {0};
|
||||||
ventoy_img_chunk *chunk;
|
ventoy_img_chunk *chunk;
|
||||||
|
grub_uint8_t disk_sig[4];
|
||||||
grub_uint8_t disk_guid[16];
|
grub_uint8_t disk_guid[16];
|
||||||
|
|
||||||
debug("ventoy_freebsd_append_conf %s\n", isopath);
|
debug("ventoy_freebsd_append_conf %s\n", isopath);
|
||||||
@@ -209,7 +210,7 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath)
|
|||||||
|
|
||||||
disk = isofile->device->disk;
|
disk = isofile->device->disk;
|
||||||
|
|
||||||
ventoy_get_disk_guid(isofile->name, disk_guid);
|
ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
@@ -217,7 +218,8 @@ static int ventoy_freebsd_append_conf(char *buf, const char *isopath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksize=%llu\n", (ulonglong)(disk->total_sectors * (1 << disk->log_sector_size)));
|
vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksize=%llu\n", (ulonglong)(disk->total_sectors * (1 << disk->log_sector_size)));
|
||||||
vtoy_ssprintf(buf, pos, "hint.ventoy.0.diskuuid=\"%s\"\n", uuid);
|
vtoy_ssprintf(buf, pos, "hint.ventoy.0.diskuuid=\"%s\"\n", uuid);
|
||||||
|
vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksignature=%02x%02x%02x%02x\n", disk_sig[0], disk_sig[1], disk_sig[2], disk_sig[3]);
|
||||||
vtoy_ssprintf(buf, pos, "hint.ventoy.0.segnum=%u\n", g_img_chunk_list.cur_chunk);
|
vtoy_ssprintf(buf, pos, "hint.ventoy.0.segnum=%u\n", g_img_chunk_list.cur_chunk);
|
||||||
|
|
||||||
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
||||||
|
@@ -49,6 +49,7 @@ static int g_vhdboot_bcd_len = 0;
|
|||||||
static int g_vhdboot_isolen = 0;
|
static int g_vhdboot_isolen = 0;
|
||||||
static char *g_vhdboot_totbuf = NULL;
|
static char *g_vhdboot_totbuf = NULL;
|
||||||
static char *g_vhdboot_isobuf = NULL;
|
static char *g_vhdboot_isobuf = NULL;
|
||||||
|
static grub_uint64_t g_img_trim_head_secnum = 0;
|
||||||
|
|
||||||
static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen)
|
static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen)
|
||||||
{
|
{
|
||||||
@@ -273,3 +274,286 @@ grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ventoy_raw_trim_head(grub_uint64_t offset)
|
||||||
|
{
|
||||||
|
grub_uint32_t i;
|
||||||
|
grub_uint32_t memsize;
|
||||||
|
grub_uint32_t imgstart = 0;
|
||||||
|
grub_uint32_t imgsecs = 0;
|
||||||
|
grub_uint64_t sectors = 0;
|
||||||
|
grub_uint64_t cursecs = 0;
|
||||||
|
grub_uint64_t delta = 0;
|
||||||
|
|
||||||
|
if ((!g_img_chunk_list.chunk) || (!offset))
|
||||||
|
{
|
||||||
|
debug("image chunk not ready %p %lu\n", g_img_chunk_list.chunk, (ulong)offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("image trim head %lu\n", (ulong)offset);
|
||||||
|
|
||||||
|
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
||||||
|
{
|
||||||
|
cursecs = g_img_chunk_list.chunk[i].disk_end_sector + 1 - g_img_chunk_list.chunk[i].disk_start_sector;
|
||||||
|
sectors += cursecs;
|
||||||
|
if (sectors >= offset)
|
||||||
|
{
|
||||||
|
delta = cursecs - (sectors - offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sectors < offset || i >= g_img_chunk_list.cur_chunk)
|
||||||
|
{
|
||||||
|
debug("Invalid size %lu %lu\n", (ulong)sectors, (ulong)offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sectors == offset)
|
||||||
|
{
|
||||||
|
memsize = (g_img_chunk_list.cur_chunk - (i + 1)) * sizeof(ventoy_img_chunk);
|
||||||
|
grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i + 1, memsize);
|
||||||
|
g_img_chunk_list.cur_chunk -= (i + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_img_chunk_list.chunk[i].disk_start_sector += delta;
|
||||||
|
g_img_chunk_list.chunk[i].img_start_sector += (grub_uint32_t)(delta / 4);
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
memsize = (g_img_chunk_list.cur_chunk - i) * sizeof(ventoy_img_chunk);
|
||||||
|
grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i, memsize);
|
||||||
|
g_img_chunk_list.cur_chunk -= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
|
||||||
|
{
|
||||||
|
imgsecs = g_img_chunk_list.chunk[i].img_end_sector + 1 - g_img_chunk_list.chunk[i].img_start_sector;
|
||||||
|
g_img_chunk_list.chunk[i].img_start_sector = imgstart;
|
||||||
|
g_img_chunk_list.chunk[i].img_end_sector = imgstart + (imgsecs - 1);
|
||||||
|
imgstart += imgsecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int offset = -1;
|
||||||
|
grub_file_t file;
|
||||||
|
vhd_footer_t vhdfoot;
|
||||||
|
VDIPREHEADER vdihdr;
|
||||||
|
char type[16] = {0};
|
||||||
|
ventoy_gpt_info *gpt;
|
||||||
|
|
||||||
|
(void)ctxt;
|
||||||
|
|
||||||
|
g_img_trim_head_secnum = 0;
|
||||||
|
|
||||||
|
if (argc != 4)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
debug("Failed to open file %s\n", args[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_snprintf(type, sizeof(type), "unknown");
|
||||||
|
|
||||||
|
grub_file_seek(file, file->size - 512);
|
||||||
|
grub_file_read(file, &vhdfoot, sizeof(vhdfoot));
|
||||||
|
|
||||||
|
if (grub_strncmp(vhdfoot.cookie, "conectix", 8) == 0)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
grub_snprintf(type, sizeof(type), "vhd%u", grub_swap_bytes32(vhdfoot.disktype));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_file_seek(file, 0);
|
||||||
|
grub_file_read(file, &vdihdr, sizeof(vdihdr));
|
||||||
|
if (vdihdr.u32Signature == VDI_IMAGE_SIGNATURE &&
|
||||||
|
grub_strncmp(vdihdr.szFileInfo, VDI_IMAGE_FILE_INFO, grub_strlen(VDI_IMAGE_FILE_INFO)) == 0)
|
||||||
|
{
|
||||||
|
offset = 2 * 1048576;
|
||||||
|
g_img_trim_head_secnum = offset / 512;
|
||||||
|
grub_snprintf(type, sizeof(type), "vdi");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
grub_snprintf(type, sizeof(type), "raw");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_env_set(args[1], type);
|
||||||
|
debug("<%s> vtoy type: <%s> ", args[0], type);
|
||||||
|
|
||||||
|
if (offset >= 0)
|
||||||
|
{
|
||||||
|
gpt = grub_zalloc(sizeof(ventoy_gpt_info));
|
||||||
|
if (!gpt)
|
||||||
|
{
|
||||||
|
grub_env_set(args[1], "unknown");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_file_seek(file, offset);
|
||||||
|
grub_file_read(file, gpt, sizeof(ventoy_gpt_info));
|
||||||
|
|
||||||
|
if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA)
|
||||||
|
{
|
||||||
|
grub_env_set(args[1], "unknown");
|
||||||
|
debug("invalid mbr signature: 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0)
|
||||||
|
{
|
||||||
|
grub_env_set(args[2], "gpt");
|
||||||
|
debug("part type: %s\n", "GPT");
|
||||||
|
|
||||||
|
if (gpt->MBR.PartTbl[0].FsFlag == 0xEE)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
{
|
||||||
|
if (grub_memcmp(gpt->PartTbl[i].PartType, "Hah!IdontNeedEFI", 16) == 0)
|
||||||
|
{
|
||||||
|
debug("part %d is grub_bios part\n", i);
|
||||||
|
grub_env_set(args[3], "1");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (gpt->PartTbl[i].LastLBA == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grub_env_set(args[2], "mbr");
|
||||||
|
debug("part type: %s\n", "MBR");
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (gpt->MBR.PartTbl[i].FsFlag == 0xEF)
|
||||||
|
{
|
||||||
|
debug("part %d is esp part in MBR mode\n", i);
|
||||||
|
grub_env_set(args[3], "1");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug("part type: %s\n", "xxx");
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
grub_check_free(gpt);
|
||||||
|
grub_file_close(file);
|
||||||
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
|
{
|
||||||
|
grub_uint32_t size = 0;
|
||||||
|
grub_uint32_t img_chunk_size = 0;
|
||||||
|
grub_file_t file;
|
||||||
|
grub_disk_t disk;
|
||||||
|
const char *pLastChain = NULL;
|
||||||
|
ventoy_chain_head *chain;
|
||||||
|
char envbuf[64];
|
||||||
|
|
||||||
|
(void)ctxt;
|
||||||
|
(void)argc;
|
||||||
|
|
||||||
|
if (NULL == g_img_chunk_list.chunk)
|
||||||
|
{
|
||||||
|
grub_printf("ventoy not ready\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_img_trim_head_secnum > 0)
|
||||||
|
{
|
||||||
|
ventoy_raw_trim_head(g_img_trim_head_secnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
|
||||||
|
|
||||||
|
size = sizeof(ventoy_chain_head) + img_chunk_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 = grub_malloc(size);
|
||||||
|
if (!chain)
|
||||||
|
{
|
||||||
|
grub_printf("Failed to alloc chain memory size %u\n", size);
|
||||||
|
grub_file_close(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain);
|
||||||
|
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_size");
|
||||||
|
|
||||||
|
grub_memset(chain, 0, sizeof(ventoy_chain_head));
|
||||||
|
|
||||||
|
/* part 1: os parameter */
|
||||||
|
g_ventoy_chain_type = ventoy_chain_linux;
|
||||||
|
ventoy_fill_os_param(file, &(chain->os_param));
|
||||||
|
|
||||||
|
/* part 2: chain head */
|
||||||
|
disk = file->device->disk;
|
||||||
|
chain->disk_drive = disk->id;
|
||||||
|
chain->disk_sector_size = (1 << disk->log_sector_size);
|
||||||
|
|
||||||
|
chain->real_img_size_in_bytes = file->size;
|
||||||
|
if (g_img_trim_head_secnum > 0)
|
||||||
|
{
|
||||||
|
chain->real_img_size_in_bytes -= g_img_trim_head_secnum * 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes;
|
||||||
|
chain->boot_catalog = 0;
|
||||||
|
|
||||||
|
/* part 3: image chunk */
|
||||||
|
chain->img_chunk_offset = sizeof(ventoy_chain_head);
|
||||||
|
chain->img_chunk_num = g_img_chunk_list.cur_chunk;
|
||||||
|
grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size);
|
||||||
|
|
||||||
|
grub_file_seek(file, g_img_trim_head_secnum * 512);
|
||||||
|
grub_file_read(file, chain->boot_catalog_sector, 512);
|
||||||
|
|
||||||
|
grub_file_close(file);
|
||||||
|
|
||||||
|
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||||
|
}
|
||||||
|
@@ -71,7 +71,7 @@ typedef struct ventoy_image_location
|
|||||||
{
|
{
|
||||||
ventoy_guid guid;
|
ventoy_guid guid;
|
||||||
|
|
||||||
/* image sector size, currently this value is always 2048 */
|
/* image sector size, 2048/512 */
|
||||||
grub_uint32_t image_sector_size;
|
grub_uint32_t image_sector_size;
|
||||||
|
|
||||||
/* disk sector size, normally the value is 512 */
|
/* disk sector size, normally the value is 512 */
|
||||||
@@ -125,7 +125,9 @@ typedef struct ventoy_os_param
|
|||||||
*/
|
*/
|
||||||
grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy
|
grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy
|
||||||
|
|
||||||
grub_uint8_t reserved[31];
|
grub_uint8_t vtoy_disk_signature[4];
|
||||||
|
|
||||||
|
grub_uint8_t reserved[27];
|
||||||
}ventoy_os_param;
|
}ventoy_os_param;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -12,10 +12,10 @@ make install
|
|||||||
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
|
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
|
||||||
|
|
||||||
net_modules_legacy="net tftp http"
|
net_modules_legacy="net tftp http"
|
||||||
all_modules_legacy="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 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="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"
|
||||||
|
|
||||||
net_modules_uefi="efinet net tftp http"
|
net_modules_uefi="efinet net tftp http"
|
||||||
all_modules_uefi="blocklist ventoy test 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="blocklist ventoy test 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"
|
||||||
|
|
||||||
if [ "$1" = "uefi" ]; then
|
if [ "$1" = "uefi" ]; then
|
||||||
all_modules="$net_modules_uefi $all_modules_uefi "
|
all_modules="$net_modules_uefi $all_modules_uefi "
|
||||||
|
@@ -33,12 +33,11 @@ if [ -e /init ] && $GREP -q '^mountroot$' /init; then
|
|||||||
fi
|
fi
|
||||||
elif [ -e "$CD_DETECT" ]; then
|
elif [ -e "$CD_DETECT" ]; then
|
||||||
echo "$CD_DETECT exist, now add hook in it..." >> $VTLOG
|
echo "$CD_DETECT exist, now add hook in it..." >> $VTLOG
|
||||||
|
|
||||||
$SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i "$CD_DETECT"
|
$SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i "$CD_DETECT"
|
||||||
TITLE_LINE=$($GREP -m1 '^hw-detect.*detect_progress_title' "$CD_DETECT")
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ -e /bin/list-devices ]; then
|
||||||
echo "add $TITLE_LINE for hook" >> $VTLOG
|
mv /bin/list-devices /bin/list-devices-bk
|
||||||
$SED "1 a$TITLE_LINE" -i "$CD_DETECT"
|
cp -a /ventoy/hook/debian/list-devices /bin/list-devices
|
||||||
fi
|
fi
|
||||||
elif [ -e /init ] && $GREP -q '/start-udev$' /init; then
|
elif [ -e /init ] && $GREP -q '/start-udev$' /init; then
|
||||||
echo "Here use notify ..." >> $VTLOG
|
echo "Here use notify ..." >> $VTLOG
|
||||||
@@ -73,5 +72,8 @@ if [ -f /mod.img ] && [ -f /mod/fs/cramfs.ko ]; then
|
|||||||
$BUSYBOX_PATH/rmmod cramfs
|
$BUSYBOX_PATH/rmmod cramfs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#for siduction-patience-nox-
|
||||||
|
if [ -f /scripts/fll ]; then
|
||||||
|
$SED "/unset FINGERED/a\\echo '/dev/mapper/ventoy';return;" -i /scripts/fll
|
||||||
|
fi
|
||||||
|
|
||||||
|
9
IMG/cpio/ventoy/hook/debian/list-devices
Normal file
9
IMG/cpio/ventoy/hook/debian/list-devices
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
if [ "$1" = "usb-partition" -a -z "$2" ]; then
|
||||||
|
if [ -f /ventoy/list-devices-usb-part ]; then
|
||||||
|
cat /ventoy/list-devices-usb-part
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
/bin/list-devices-bk $*
|
@@ -42,6 +42,7 @@ if ! [ -e $VTOY_DM_PATH ]; then
|
|||||||
blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/')
|
blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/')
|
||||||
mknod -m 0666 $VTOY_DM_PATH b $blkdev_num
|
mknod -m 0666 $VTOY_DM_PATH b $blkdev_num
|
||||||
fi
|
fi
|
||||||
|
cp -a $VTOY_DM_PATH /dev/ventoy
|
||||||
|
|
||||||
PATH=$VTPATH_OLD
|
PATH=$VTPATH_OLD
|
||||||
|
|
||||||
|
@@ -19,4 +19,4 @@
|
|||||||
|
|
||||||
$SED '1 apmedia=usbhd' -i /init
|
$SED '1 apmedia=usbhd' -i /init
|
||||||
$SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/puppy-disk.sh" -i /init
|
$SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/puppy-disk.sh" -i /init
|
||||||
$SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='mapper/ventoy|iso9660'" -i /init
|
$SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='ventoy|iso9660'" -i /init
|
||||||
|
@@ -133,15 +133,7 @@ else
|
|||||||
vtlog "boot=, or casper, don't mount"
|
vtlog "boot=, or casper, don't mount"
|
||||||
else
|
else
|
||||||
vtlog "No boot param, need to mount"
|
vtlog "No boot param, need to mount"
|
||||||
$BUSYBOX_PATH/mkdir /cdrom
|
echo /dev/$1 > /ventoy/list-devices-usb-part
|
||||||
|
|
||||||
if [ -b $VTOY_DM_PATH ]; then
|
|
||||||
vtlog "mount $VTOY_DM_PATH ..."
|
|
||||||
$BUSYBOX_PATH/mount -t iso9660 $VTOY_DM_PATH /cdrom
|
|
||||||
else
|
|
||||||
vtlog "mount /dev/$1 ..."
|
|
||||||
$BUSYBOX_PATH/mount -t iso9660 /dev/$1 /cdrom
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
if $GREP -q kaspersky /proc/version; then
|
if $GREP -q kaspersky /proc/version; then
|
||||||
$SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
|
$SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
|
||||||
|
if [ -f /ventoy/ventoy_persistent_map ]; then
|
||||||
|
$SED "/sysresccd_parsecmdline[^(]*$/a\ BACKSTORE_CMD='LABEL=casper-rw,noloop'" -i /init
|
||||||
|
fi
|
||||||
elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then
|
elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then
|
||||||
ventoy_systemd_udevd_work_around
|
ventoy_systemd_udevd_work_around
|
||||||
ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
|
ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
|
||||||
|
66
IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh
Normal file
66
IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/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 $* ############"
|
||||||
|
|
||||||
|
if is_ventoy_hook_finished; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait_for_usb_disk_ready
|
||||||
|
|
||||||
|
vtdiskname=$(get_ventoy_disk_name)
|
||||||
|
if [ "$vtdiskname" = "unknown" ]; then
|
||||||
|
vtlog "ventoy disk not found"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
|
||||||
|
|
||||||
|
blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/')
|
||||||
|
vtDM=$(ventoy_find_dm_id ${blkdev_num})
|
||||||
|
vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..."
|
||||||
|
|
||||||
|
while [ -n "Y" ]; do
|
||||||
|
if [ -b /dev/$vtDM ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 0.3
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
vtlog "ln -s /dev/$vtDM $1"
|
||||||
|
ln -s /dev/$vtDM "$1"
|
||||||
|
else
|
||||||
|
vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/')
|
||||||
|
vtlog "vtLABEL is $vtLABEL"
|
||||||
|
|
||||||
|
if [ -z "$vtLABEL" ]; then
|
||||||
|
vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline)
|
||||||
|
vtlog "vtLABEL is $vtLABEL from cmdline"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OK finish
|
||||||
|
set_ventoy_hook_finish
|
@@ -28,8 +28,22 @@ else
|
|||||||
$CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$DISTRO_UDEV_DIR/13-dm-disk.rules"
|
$CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$DISTRO_UDEV_DIR/13-dm-disk.rules"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if $GREP -q '^"$mount_handler"' /init; then
|
||||||
if $GREP -q '^mount_setup$' init; then
|
echo 'use mount_handler ...' >> $VTLOG
|
||||||
|
|
||||||
|
vthookfile=/hooks/archiso
|
||||||
|
|
||||||
|
if [ -e /hooks/miso ]; then
|
||||||
|
vthookfile=/hooks/miso
|
||||||
|
$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$misodevice\"" -i /init
|
||||||
|
else
|
||||||
|
$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$archisodevice\"" -i /init
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $vthookfile ]; then
|
||||||
|
$SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/manjaro/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile
|
||||||
|
fi
|
||||||
|
elif $GREP -q '^mount_setup$' init; then
|
||||||
echo "Here use notify ..." >> $VTLOG
|
echo "Here use notify ..." >> $VTLOG
|
||||||
|
|
||||||
ventoy_set_inotify_script manjaro/ventoy-inotifyd-hook.sh
|
ventoy_set_inotify_script manjaro/ventoy-inotifyd-hook.sh
|
||||||
|
@@ -87,7 +87,13 @@ wait_for_usb_disk_ready() {
|
|||||||
usb_disk=$(get_ventoy_disk_name)
|
usb_disk=$(get_ventoy_disk_name)
|
||||||
vtlog "wait_for_usb_disk_ready $usb_disk ..."
|
vtlog "wait_for_usb_disk_ready $usb_disk ..."
|
||||||
|
|
||||||
if [ -e "${usb_disk}2" ]; then
|
if echo $usb_disk | $EGREP -q "nvme|mmc"; then
|
||||||
|
vtpart2=${usb_disk}p2
|
||||||
|
else
|
||||||
|
vtpart2=${usb_disk}2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e "${vtpart2}" ]; then
|
||||||
vtlog "wait_for_usb_disk_ready $usb_disk finish"
|
vtlog "wait_for_usb_disk_ready $usb_disk finish"
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
@@ -105,7 +111,13 @@ is_ventoy_disk() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
not_ventoy_disk() {
|
not_ventoy_disk() {
|
||||||
if $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c "$1"; then
|
if echo $1 | $EGREP -q "nvme.*p$|mmc.*p$"; then
|
||||||
|
vtDiskName=${1:0:-1}
|
||||||
|
else
|
||||||
|
vtDiskName=$1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c "$vtDiskName"; then
|
||||||
$BUSYBOX_PATH/false
|
$BUSYBOX_PATH/false
|
||||||
else
|
else
|
||||||
$BUSYBOX_PATH/true
|
$BUSYBOX_PATH/true
|
||||||
@@ -463,9 +475,12 @@ ventoy_create_persistent_link() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ventoy_udev_disk_common_hook() {
|
ventoy_udev_disk_common_hook() {
|
||||||
|
if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$"; then
|
||||||
VTDISK="${1:0:-1}"
|
VTDISK="${1:0:-2}"
|
||||||
|
else
|
||||||
|
VTDISK="${1:0:-1}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -e /vtoy/vtoy ]; then
|
if [ -e /vtoy/vtoy ]; then
|
||||||
VTRWMOD=""
|
VTRWMOD=""
|
||||||
@@ -533,8 +548,14 @@ is_inotify_ventoy_part() {
|
|||||||
if echo $1 | $GREP -q "2$"; then
|
if echo $1 | $GREP -q "2$"; then
|
||||||
if ! [ -e /sys/block/$1 ]; then
|
if ! [ -e /sys/block/$1 ]; then
|
||||||
if [ -e /sys/class/block/$1 ]; then
|
if [ -e /sys/class/block/$1 ]; then
|
||||||
if [ -e /dev/${1:0:-1} ]; then
|
if echo $1 | $EGREP -q "nvme|mmc"; then
|
||||||
$VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c ${1:0:-1}
|
vtShortName=${1:0:-2}
|
||||||
|
else
|
||||||
|
vtShortName=${1:0:-1}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e /dev/$vtShortName ]; then
|
||||||
|
$VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c $vtShortName
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
Binary file not shown.
@@ -1,5 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
if ! [ -f ./tool/ventoy_lib.sh ]; then
|
||||||
|
if [ -f ${0%Ventoy2Disk.sh}/tool/ventoy_lib.sh ]; then
|
||||||
|
cd ${0%Ventoy2Disk.sh}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f ./ventoy/version ]; then
|
if [ -f ./ventoy/version ]; then
|
||||||
curver=$(cat ./ventoy/version)
|
curver=$(cat ./ventoy/version)
|
||||||
fi
|
fi
|
||||||
@@ -12,13 +18,8 @@ echo " https://www.ventoy.net"
|
|||||||
echo '**********************************************'
|
echo '**********************************************'
|
||||||
echo ''
|
echo ''
|
||||||
|
|
||||||
OLDDIR=$PWD
|
OLDDIR=$(pwd)
|
||||||
|
PATH=./tool:$PATH
|
||||||
if ! [ -f ./tool/xzcat ]; then
|
|
||||||
if [ -f ${0%Ventoy2Disk.sh}/tool/xzcat ]; then
|
|
||||||
cd ${0%Ventoy2Disk.sh}
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [ -f ./boot/boot.img ]; then
|
if ! [ -f ./boot/boot.img ]; then
|
||||||
if [ -d ./grub ]; then
|
if [ -d ./grub ]; then
|
||||||
@@ -30,27 +31,30 @@ if ! [ -f ./boot/boot.img ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "############# Ventoy2Disk $* ################" >> ./log.txt
|
echo "############# Ventoy2Disk $* ################" >> ./log.txt
|
||||||
|
date >> ./log.txt
|
||||||
|
|
||||||
#decompress tool
|
#decompress tool
|
||||||
if ! [ -f ./tool/ash ]; then
|
if [ -f ./tool/VentoyWorker.sh ]; then
|
||||||
|
echo "no need to decompress tools" >> ./log.txt
|
||||||
|
else
|
||||||
cd tool
|
cd tool
|
||||||
chmod +x ./xzcat
|
|
||||||
|
if [ -f ./xzcat ]; then
|
||||||
|
chmod +x ./xzcat
|
||||||
|
fi
|
||||||
|
|
||||||
for file in $(ls *.xz); do
|
for file in $(ls *.xz); do
|
||||||
./xzcat $file > ${file%.xz}
|
xzcat $file > ${file%.xz}
|
||||||
chmod +x ${file%.xz}
|
chmod +x ${file%.xz}
|
||||||
done
|
done
|
||||||
cd ../
|
cd ../
|
||||||
|
|
||||||
if ! [ -f ./tool/ash ]; then
|
|
||||||
echo 'Failed to decompress tools ...'
|
|
||||||
if [ -n "$OLDDIR" ]; then
|
|
||||||
cd $OLDDIR
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./tool/ash ./tool/VentoyWorker.sh $*
|
if [ -f /bin/bash ]; then
|
||||||
|
bash ./tool/VentoyWorker.sh $*
|
||||||
|
else
|
||||||
|
./tool/ash ./tool/VentoyWorker.sh $*
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$OLDDIR" ]; then
|
if [ -n "$OLDDIR" ]; then
|
||||||
cd $OLDDIR
|
cd $OLDDIR
|
||||||
|
@@ -74,7 +74,25 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json {
|
|||||||
echo -e "\npress ENTER to exit ..."
|
echo -e "\npress ENTER to exit ..."
|
||||||
read vtInputKey
|
read vtInputKey
|
||||||
unset pager
|
unset pager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menuentry 'Check image list plugin configuration' --class=debug_imagelist {
|
||||||
|
set pager=1
|
||||||
|
vt_check_plugin_json $vt_plugin_path image_list $vtoy_iso_part
|
||||||
|
|
||||||
|
echo -e "\npress ENTER to exit ..."
|
||||||
|
read vtInputKey
|
||||||
|
unset pager
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry 'Check boot conf replace plugin configuration' --class=debug_bootconf_replace {
|
||||||
|
set pager=1
|
||||||
|
vt_check_plugin_json $vt_plugin_path conf_replace $vtoy_iso_part
|
||||||
|
|
||||||
|
echo -e "\npress ENTER to exit ..."
|
||||||
|
read vtInputKey
|
||||||
|
unset pager
|
||||||
|
}
|
||||||
|
|
||||||
menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
|
menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
|
||||||
echo 'Return ...'
|
echo 'Return ...'
|
||||||
@@ -107,7 +125,17 @@ submenu "Resolution Configuration" --class=debug_resolution {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submenu "Screen Display Mode" --class=debug_screen_mode {
|
||||||
|
menuentry 'Force Text Mode' --class=debug_text_mode {
|
||||||
|
terminal_output console
|
||||||
|
}
|
||||||
|
menuentry 'Force Graphics Mode' --class=debug_gui_mode {
|
||||||
|
terminal_output gfxterm
|
||||||
|
}
|
||||||
|
menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
|
||||||
|
echo 'Return ...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$grub_platform" != "pc" ]; then
|
if [ "$grub_platform" != "pc" ]; then
|
||||||
submenu 'Ventoy UEFI Utilities' --class=debug_util {
|
submenu 'Ventoy UEFI Utilities' --class=debug_util {
|
||||||
|
@@ -44,6 +44,12 @@ function ventoy_gui_console {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ventoy_acpi_param {
|
||||||
|
if [ "$VTOY_PARAM_NO_ACPI" != "1" ]; then
|
||||||
|
vt_acpi_param $1 $2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function ventoy_power {
|
function ventoy_power {
|
||||||
configfile $prefix/power.cfg
|
configfile $prefix/power.cfg
|
||||||
}
|
}
|
||||||
@@ -53,7 +59,7 @@ function ventoy_diagnosis {
|
|||||||
configfile $prefix/debug.cfg
|
configfile $prefix/debug.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
function ventoy_localboot {
|
function ventoy_localboot {
|
||||||
configfile $prefix/localboot.cfg
|
configfile $prefix/localboot.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +258,21 @@ function distro_specify_initrd_file_phase2 {
|
|||||||
if [ "$grub_platform" != "pc" ]; then
|
if [ "$grub_platform" != "pc" ]; then
|
||||||
vt_add_replace_file 0 "minimal\\x86_64\\rootfs.xz"
|
vt_add_replace_file 0 "minimal\\x86_64\\rootfs.xz"
|
||||||
fi
|
fi
|
||||||
|
elif [ -f (loop)/arch/boot/x86_64/archiso.img ]; then
|
||||||
|
vt_linux_specify_initrd_file /arch/boot/x86_64/archiso.img
|
||||||
|
if [ "$grub_platform" != "pc" ]; then
|
||||||
|
vt_add_replace_file 0 "EFI\\archiso\\archiso.img"
|
||||||
|
fi
|
||||||
|
elif [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then
|
||||||
|
vt_linux_specify_initrd_file /blackarch/boot/x86_64/archiso.img
|
||||||
|
|
||||||
|
elif [ -f (loop)/install.amd/initrd.gz ]; then
|
||||||
|
vt_linux_specify_initrd_file /live/initrd2.img
|
||||||
|
vt_linux_specify_initrd_file /install.amd/initrd.gz
|
||||||
|
vt_linux_specify_initrd_file /install.amd/gtk/initrd.gz
|
||||||
|
elif [ -f (loop)/boot/grub/kernels.cfg ]; then
|
||||||
|
vt_linux_parse_initrd_grub file (loop)/boot/grub/kernels.cfg
|
||||||
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,6 +450,7 @@ function uefi_windows_menu_func {
|
|||||||
ventoy_debug_pause
|
ventoy_debug_pause
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
ventoy_cli_console
|
ventoy_cli_console
|
||||||
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
@@ -440,6 +461,7 @@ function uefi_windows_menu_func {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function uefi_linux_menu_func {
|
function uefi_linux_menu_func {
|
||||||
|
|
||||||
if [ "$ventoy_compatible" = "NO" ]; then
|
if [ "$ventoy_compatible" = "NO" ]; then
|
||||||
|
|
||||||
if [ "$ventoy_fs_probe" = "udf" ]; then
|
if [ "$ventoy_fs_probe" = "udf" ]; then
|
||||||
@@ -472,6 +494,7 @@ function uefi_linux_menu_func {
|
|||||||
distro_specify_initrd_file
|
distro_specify_initrd_file
|
||||||
|
|
||||||
vt_linux_initrd_count vtcount
|
vt_linux_initrd_count vtcount
|
||||||
|
|
||||||
if [ $vtcount -eq 0 ]; then
|
if [ $vtcount -eq 0 ]; then
|
||||||
distro_specify_initrd_file_phase2
|
distro_specify_initrd_file_phase2
|
||||||
|
|
||||||
@@ -490,9 +513,19 @@ function uefi_linux_menu_func {
|
|||||||
if [ -d (loop)/arch ]; then
|
if [ -d (loop)/arch ]; then
|
||||||
if [ -f (loop)/arch/boot/x86_64/archiso.img ]; then
|
if [ -f (loop)/arch/boot/x86_64/archiso.img ]; then
|
||||||
vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img"
|
vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img"
|
||||||
|
elif [ -f (loop)/arch/boot/x86_64/initramfs-linux.img ]; then
|
||||||
|
vt_add_replace_file $vtindex "arch\\boot\\x86_64\\initramfs-linux.img"
|
||||||
elif [ -f (loop)/boot/initramfs_x86_64.img ]; then
|
elif [ -f (loop)/boot/initramfs_x86_64.img ]; then
|
||||||
vt_add_replace_file $vtindex "boot\\initramfs_x86_64.img"
|
vt_add_replace_file $vtindex "boot\\initramfs_x86_64.img"
|
||||||
fi
|
fi
|
||||||
|
elif [ -d (loop)/blackarch ]; then
|
||||||
|
if [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then
|
||||||
|
vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img"
|
||||||
|
fi
|
||||||
|
elif [ -d (loop)/parabola ]; then
|
||||||
|
if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then
|
||||||
|
vt_add_replace_file $vtindex "EFI\\parabolaiso\\parabolaiso.img"
|
||||||
|
fi
|
||||||
elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then
|
elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then
|
||||||
vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz"
|
vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz"
|
||||||
elif [ -f (loop)/loader/entries/thinstation.conf ]; then
|
elif [ -f (loop)/loader/entries/thinstation.conf ]; then
|
||||||
@@ -508,7 +541,7 @@ function uefi_linux_menu_func {
|
|||||||
fi
|
fi
|
||||||
elif [ -d (loop)/EFI/BOOT/entries ]; then
|
elif [ -d (loop)/EFI/BOOT/entries ]; then
|
||||||
if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then
|
if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then
|
||||||
vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img"
|
vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img"
|
||||||
fi
|
fi
|
||||||
elif [ -e (loop)/syslinux/alt0/full.cz ]; then
|
elif [ -e (loop)/syslinux/alt0/full.cz ]; then
|
||||||
vt_add_replace_file 0 "EFI\\BOOT\\full.cz"
|
vt_add_replace_file 0 "EFI\\BOOT\\full.cz"
|
||||||
@@ -522,6 +555,7 @@ function uefi_linux_menu_func {
|
|||||||
vt_linux_chain_data ${1}${chosen_path}
|
vt_linux_chain_data ${1}${chosen_path}
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
ventoy_cli_console
|
ventoy_cli_console
|
||||||
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
@@ -535,6 +569,7 @@ function uefi_unix_menu_func {
|
|||||||
ventoy_unix_comm_proc $1 ${chosen_path}
|
ventoy_unix_comm_proc $1 ${chosen_path}
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
ventoy_cli_console
|
ventoy_cli_console
|
||||||
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
@@ -587,11 +622,15 @@ function uefi_iso_menu_func {
|
|||||||
elif vt_check_mode 1; then
|
elif vt_check_mode 1; then
|
||||||
set ventoy_compatible=YES
|
set ventoy_compatible=YES
|
||||||
else
|
else
|
||||||
vt_check_compatible (loop)
|
vt_check_compatible (loop)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
vt_img_sector ${1}${chosen_path}
|
vt_img_sector ${1}${chosen_path}
|
||||||
|
|
||||||
|
if [ "$ventoy_fs_probe" = "iso9660" ]; then
|
||||||
|
vt_select_conf_replace ${1} ${chosen_path}
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$vtoy_os" = "Windows" ]; then
|
if [ "$vtoy_os" = "Windows" ]; then
|
||||||
vt_check_compatible_pe (loop)
|
vt_check_compatible_pe (loop)
|
||||||
uefi_windows_menu_func $1 ${chosen_path}
|
uefi_windows_menu_func $1 ${chosen_path}
|
||||||
@@ -646,9 +685,8 @@ function legacy_windows_menu_func {
|
|||||||
ventoy_debug_pause
|
ventoy_debug_pause
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
set gfxmode=1920x1080,1366x768,1024x768,800x600,auto
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
terminal_output gfxterm
|
|
||||||
boot
|
boot
|
||||||
else
|
else
|
||||||
echo "chain empty failed"
|
echo "chain empty failed"
|
||||||
@@ -712,6 +750,7 @@ function legacy_linux_menu_func {
|
|||||||
ventoy_debug_pause
|
ventoy_debug_pause
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
else
|
else
|
||||||
@@ -725,6 +764,7 @@ function legacy_unix_menu_func {
|
|||||||
ventoy_unix_comm_proc $1 ${chosen_path}
|
ventoy_unix_comm_proc $1 ${chosen_path}
|
||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
#ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
|
||||||
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
else
|
else
|
||||||
@@ -754,7 +794,7 @@ function legacy_iso_menu_func {
|
|||||||
loopback loop ${1}${chosen_path}
|
loopback loop ${1}${chosen_path}
|
||||||
|
|
||||||
get_os_type (loop)
|
get_os_type (loop)
|
||||||
|
|
||||||
if [ -n "$vtcompat" ]; then
|
if [ -n "$vtcompat" ]; then
|
||||||
set ventoy_compatible=YES
|
set ventoy_compatible=YES
|
||||||
unset vtcompat
|
unset vtcompat
|
||||||
@@ -766,6 +806,10 @@ function legacy_iso_menu_func {
|
|||||||
|
|
||||||
vt_img_sector ${1}${chosen_path}
|
vt_img_sector ${1}${chosen_path}
|
||||||
|
|
||||||
|
if [ "$ventoy_fs_probe" = "iso9660" ]; then
|
||||||
|
vt_select_conf_replace ${1} ${chosen_path}
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$vtoy_os" = "Windows" ]; then
|
if [ "$vtoy_os" = "Windows" ]; then
|
||||||
vt_check_compatible_pe (loop)
|
vt_check_compatible_pe (loop)
|
||||||
legacy_windows_menu_func $1 ${chosen_path}
|
legacy_windows_menu_func $1 ${chosen_path}
|
||||||
@@ -900,9 +944,7 @@ function wim_common_menuentry {
|
|||||||
|
|
||||||
if [ -n "$vtoy_chain_mem_addr" ]; then
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
if [ "$grub_platform" = "pc" ]; then
|
if [ "$grub_platform" = "pc" ]; then
|
||||||
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
set gfxmode=1920x1080,1366x768,1024x768,800x600,auto
|
|
||||||
terminal_output gfxterm
|
|
||||||
else
|
else
|
||||||
ventoy_cli_console
|
ventoy_cli_console
|
||||||
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
@@ -945,7 +987,6 @@ function efi_unsupport_menuentry {
|
|||||||
common_unsupport_menuentry
|
common_unsupport_menuentry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function vhd_common_menuentry {
|
function vhd_common_menuentry {
|
||||||
|
|
||||||
if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then
|
if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then
|
||||||
@@ -959,17 +1000,14 @@ function vhd_common_menuentry {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
vt_chosen_img_path vt_chosen_path vt_chosen_size
|
vt_chosen_img_path vt_chosen_path vt_chosen_size
|
||||||
vt_patch_vhdboot ${vt_chosen_path}
|
vt_patch_vhdboot $vt_chosen_path
|
||||||
|
|
||||||
ventoy_debug_pause
|
ventoy_debug_pause
|
||||||
|
|
||||||
if [ -n "$vtoy_vhd_buf_addr" ]; then
|
if [ -n "$vtoy_vhd_buf_addr" ]; then
|
||||||
if [ "$grub_platform" = "pc" ]; then
|
if [ "$grub_platform" = "pc" ]; then
|
||||||
linux16 $vtoy_path/memdisk iso raw
|
linux16 $vtoy_path/memdisk iso raw
|
||||||
initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
|
initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
|
||||||
|
|
||||||
set gfxmode=1920x1080,1366x768,1024x768,800x600,auto
|
|
||||||
terminal_output gfxterm
|
|
||||||
boot
|
boot
|
||||||
else
|
else
|
||||||
ventoy_cli_console
|
ventoy_cli_console
|
||||||
@@ -978,7 +1016,7 @@ function vhd_common_menuentry {
|
|||||||
ventoy_gui_console
|
ventoy_gui_console
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Failed to boot vhd file"
|
echo "Please put the right ventoy_vhdboot.img file to the 1st partition"
|
||||||
ventoy_pause
|
ventoy_pause
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -987,6 +1025,71 @@ function vhd_unsupport_menuentry {
|
|||||||
common_unsupport_menuentry
|
common_unsupport_menuentry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function vtoyboot_common_func {
|
||||||
|
set AltBootPart=0
|
||||||
|
set vtoysupport=0
|
||||||
|
|
||||||
|
vt_get_vtoy_type ${1} vtoytype parttype AltBootPart
|
||||||
|
|
||||||
|
if vt_str_begin $vtoytype vhd; then
|
||||||
|
set vtoysupport=1
|
||||||
|
elif [ "$vtoytype" = "raw" ]; then
|
||||||
|
set vtoysupport=1
|
||||||
|
elif [ "$vtoytype" = "vdi" ]; then
|
||||||
|
set vtoysupport=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $vtoysupport -eq 1 ]; then
|
||||||
|
if [ "$grub_platform" = "pc" ]; then
|
||||||
|
if [ "$parttype" = "gpt" -a $AltBootPart -eq 0 ]; then
|
||||||
|
echo "The OS in the vdisk was created in UEFI mode, but current is Legacy BIOS mode."
|
||||||
|
echo "虚拟磁盘内的系统是在UEFI模式下创建的,而当前系统是Legacy BIOS模式,可能无法正常启动。"
|
||||||
|
ventoy_pause
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$parttype" = "mbr" -a $AltBootPart -eq 0 ]; then
|
||||||
|
echo "The OS in the vdisk was created in Legacy BIOS mode, but current is UEFI mode."
|
||||||
|
echo "虚拟磁盘内的系统是在Legacy BIOS模式下创建的,而当前系统是UEFI模式,可能无法正常启动。"
|
||||||
|
ventoy_pause
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
vt_img_sector ${1}
|
||||||
|
vt_raw_chain_data ${1}
|
||||||
|
|
||||||
|
ventoy_debug_pause
|
||||||
|
|
||||||
|
if [ -n "$vtoy_chain_mem_addr" ]; then
|
||||||
|
if [ "$grub_platform" = "pc" ]; then
|
||||||
|
vt_acpi_param ${vtoy_chain_mem_addr} 512
|
||||||
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} bios80 sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
|
boot
|
||||||
|
else
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 512
|
||||||
|
ventoy_cli_console
|
||||||
|
chainloader ${vtoy_path}/ventoy_x64.efi sector512 env_param=${ventoy_env_param} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
|
boot
|
||||||
|
ventoy_gui_console
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "chain empty failed!"
|
||||||
|
ventoy_pause
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Unsupported vtoy type $vtoytype"
|
||||||
|
ventoy_pause
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function vtoy_common_menuentry {
|
||||||
|
vt_chosen_img_path vt_chosen_path vt_chosen_size
|
||||||
|
vtoyboot_common_func ${vtoy_iso_part}${vt_chosen_path}
|
||||||
|
}
|
||||||
|
|
||||||
|
function vtoy_unsupport_menuentry {
|
||||||
|
common_unsupport_menuentry
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
#============================================================#
|
#============================================================#
|
||||||
# IMG file boot process #
|
# IMG file boot process #
|
||||||
@@ -1228,10 +1331,12 @@ function img_common_menuentry {
|
|||||||
ventoy_img_memtest86
|
ventoy_img_memtest86
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
vt_linux_chain_data ${vtoy_iso_part}${vt_chosen_path}
|
||||||
|
ventoy_acpi_param ${vtoy_chain_mem_addr} 512
|
||||||
if [ "$grub_platform" = "pc" ]; then
|
if [ "$grub_platform" = "pc" ]; then
|
||||||
img_unsupport_tip
|
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
else
|
boot
|
||||||
vt_linux_chain_data ${vtoy_iso_part}${vt_chosen_path}
|
else
|
||||||
chainloader ${vtoy_path}/ventoy_x64.efi sector512 env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
chainloader ${vtoy_path}/ventoy_x64.efi sector512 env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
|
||||||
boot
|
boot
|
||||||
fi
|
fi
|
||||||
@@ -1255,7 +1360,10 @@ function img_unsupport_menuentry {
|
|||||||
#############################################################
|
#############################################################
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
set VENTOY_VERSION="1.0.21"
|
set VENTOY_VERSION="1.0.28"
|
||||||
|
|
||||||
|
#ACPI not compatible with Window7/8, so disable by default
|
||||||
|
set VTOY_PARAM_NO_ACPI=1
|
||||||
|
|
||||||
# Default menu display mode, you can change it as you want.
|
# Default menu display mode, you can change it as you want.
|
||||||
# 0: List mode
|
# 0: List mode
|
||||||
@@ -1292,7 +1400,7 @@ if [ "$vtoy_dev" = "tftp" ]; then
|
|||||||
loadfont ascii
|
loadfont ascii
|
||||||
|
|
||||||
if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
|
if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
|
||||||
set vt_plugin_path=$vtoy_iso_part
|
set vt_plugin_path=$vtoy_iso_part
|
||||||
else
|
else
|
||||||
set vt_plugin_path=$prefix
|
set vt_plugin_path=$prefix
|
||||||
vt_load_plugin $vt_plugin_path
|
vt_load_plugin $vt_plugin_path
|
||||||
@@ -1351,10 +1459,11 @@ if [ -n "$vtoy_gfxmode" ]; then
|
|||||||
set gfxmode=$vtoy_gfxmode
|
set gfxmode=$vtoy_gfxmode
|
||||||
set gfxpayload=keep
|
set gfxpayload=keep
|
||||||
else
|
else
|
||||||
set gfxmode=1920x1080,1366x768,1024x768,800x600,auto
|
set gfxmode=1024x768
|
||||||
set gfxpayload=keep
|
set gfxpayload=keep
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ "$vtoy_display_mode" = "CLI" ]; then
|
if [ "$vtoy_display_mode" = "CLI" ]; then
|
||||||
terminal_output console
|
terminal_output console
|
||||||
elif [ "$vtoy_display_mode" = "serial" ]; then
|
elif [ "$vtoy_display_mode" = "serial" ]; then
|
||||||
@@ -1378,17 +1487,55 @@ else
|
|||||||
terminal_output gfxterm
|
terminal_output gfxterm
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$VTOY_PLUGIN_SYNTAX_ERROR" ]; then
|
||||||
|
clear
|
||||||
|
echo -e "\n Syntax error detected in ventoy.json, please check! \n"
|
||||||
|
echo -e " ventoy.json 文件中有语法错误,所有配置都不会生效,请检查!\n"
|
||||||
|
echo -e "\n press ENTER to continue (请按 回车 键继续) ..."
|
||||||
|
read vtInputKey
|
||||||
|
fi
|
||||||
|
|
||||||
#export necessary variable
|
#export necessary variable
|
||||||
export theme
|
export theme
|
||||||
export gfxmode
|
export gfxmode
|
||||||
|
export gfxpayload
|
||||||
export vtoydev
|
export vtoydev
|
||||||
|
export vtoy_path
|
||||||
|
export vtdebug_flag
|
||||||
export vtoy_iso_part
|
export vtoy_iso_part
|
||||||
export vtoy_efi_part
|
export vtoy_efi_part
|
||||||
export VENTOY_VERSION
|
export VENTOY_VERSION
|
||||||
export VTOY_CUR_VIDEO_MODE
|
export VTOY_CUR_VIDEO_MODE
|
||||||
|
|
||||||
|
#special VTOY_DEFAULT_IMAGE process
|
||||||
|
if [ -n "$VTOY_DEFAULT_IMAGE" ]; then
|
||||||
|
if regexp --set 1:vtHotkey --set 2:vtDefault "(F[2-9])>(.*)" "$VTOY_DEFAULT_IMAGE"; then
|
||||||
|
|
||||||
|
set default="$vtDefault"
|
||||||
|
if [ -z "$VTOY_MENU_TIMEOUT" ]; then
|
||||||
|
set timeout=0
|
||||||
|
else
|
||||||
|
set timeout=$VTOY_MENU_TIMEOUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
export timeout
|
||||||
|
export default
|
||||||
|
|
||||||
|
if [ "$vtHotkey" = "F2" ]; then
|
||||||
|
ventoy_power
|
||||||
|
elif [ "$vtHotkey" = "F4" ]; then
|
||||||
|
ventoy_localboot
|
||||||
|
elif [ "$vtHotkey" = "F5" ]; then
|
||||||
|
ventoy_diagnosis
|
||||||
|
elif [ "$vtHotkey" = "F6" ]; then
|
||||||
|
ventoy_ext_menu
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset timeout
|
||||||
|
unset default
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
#colect all image files (iso files)
|
#colect all image files (iso files)
|
||||||
set ventoy_img_count=0
|
set ventoy_img_count=0
|
||||||
|
Binary file not shown.
@@ -122,7 +122,7 @@ crypto:
|
|||||||
part_bsd: part_msdos
|
part_bsd: part_msdos
|
||||||
cs5536: pci
|
cs5536: pci
|
||||||
biosdisk:
|
biosdisk:
|
||||||
ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha1 relocator iso9660
|
ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha1 relocator iso9660 acpi
|
||||||
lsapm:
|
lsapm:
|
||||||
gcry_sha512: crypto
|
gcry_sha512: crypto
|
||||||
password: crypto normal
|
password: crypto normal
|
||||||
|
@@ -21,7 +21,12 @@ if [ "$grub_platform" = "pc" ]; then
|
|||||||
if search -n -s -f /Boot/BCD; then
|
if search -n -s -f /Boot/BCD; then
|
||||||
for bt in bootmgr BOOTMGR Bootmgr BootMGR; do
|
for bt in bootmgr BOOTMGR Bootmgr BootMGR; do
|
||||||
if [ -f /$bt ]; then
|
if [ -f /$bt ]; then
|
||||||
ntldr /$bt
|
if regexp '^hd0' $root; then
|
||||||
|
ntldr /$bt
|
||||||
|
else
|
||||||
|
drivemap -s hd0 $root
|
||||||
|
ntldr /$bt
|
||||||
|
fi
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@@ -119,7 +119,7 @@ ehci: cs5536 usb boot
|
|||||||
crypto:
|
crypto:
|
||||||
part_bsd: part_msdos
|
part_bsd: part_msdos
|
||||||
cs5536:
|
cs5536:
|
||||||
ventoy: ext2 fshelp crypto font exfat udf extcmd normal video gcry_sha1 iso9660
|
ventoy: ext2 fshelp font crypto exfat udf extcmd normal video gcry_sha1 iso9660
|
||||||
gcry_sha512: crypto
|
gcry_sha512: crypto
|
||||||
password: crypto normal
|
password: crypto normal
|
||||||
fshelp:
|
fshelp:
|
||||||
|
Binary file not shown.
@@ -14,9 +14,12 @@ print_usage() {
|
|||||||
echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)'
|
echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)'
|
||||||
echo ' -s enable secure boot support (default is disabled)'
|
echo ' -s enable secure boot support (default is disabled)'
|
||||||
echo ' -g use GPT partition style, default is MBR (only for install)'
|
echo ' -g use GPT partition style, default is MBR (only for install)'
|
||||||
|
echo ' -L Label of the 1st exfat partition (default is ventoy)'
|
||||||
echo ''
|
echo ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VTNEW_LABEL='ventoy'
|
||||||
RESERVE_SIZE_MB=0
|
RESERVE_SIZE_MB=0
|
||||||
while [ -n "$1" ]; do
|
while [ -n "$1" ]; do
|
||||||
if [ "$1" = "-i" ]; then
|
if [ "$1" = "-i" ]; then
|
||||||
@@ -30,6 +33,9 @@ while [ -n "$1" ]; do
|
|||||||
SECUREBOOT="YES"
|
SECUREBOOT="YES"
|
||||||
elif [ "$1" = "-g" ]; then
|
elif [ "$1" = "-g" ]; then
|
||||||
VTGPT="YES"
|
VTGPT="YES"
|
||||||
|
elif [ "$1" = "-L" ]; then
|
||||||
|
shift
|
||||||
|
VTNEW_LABEL=$1
|
||||||
elif [ "$1" = "-r" ]; then
|
elif [ "$1" = "-r" ]; then
|
||||||
RESERVE_SPACE="YES"
|
RESERVE_SPACE="YES"
|
||||||
shift
|
shift
|
||||||
@@ -62,7 +68,11 @@ if ! [ -b "$DISK" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -e /sys/class/block/${DISK#/dev/}/start ]; then
|
if [ -e /sys/class/block/${DISK#/dev/}/start ]; then
|
||||||
vterr "$DISK is a partition, please use the whole disk"
|
vterr "$DISK is a partition, please use the whole disk."
|
||||||
|
echo "For example:"
|
||||||
|
vterr " sudo sh Ventoy2Disk.sh -i /dev/sdX1 <=== This is wrong"
|
||||||
|
vtinfo " sudo sh Ventoy2Disk.sh -i /dev/sdX <=== This is right"
|
||||||
|
echo ""
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -75,6 +85,7 @@ if [ -n "$RESERVE_SPACE" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#check access
|
||||||
if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then
|
if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then
|
||||||
vtdebug "root permission check ok ..."
|
vtdebug "root permission check ok ..."
|
||||||
else
|
else
|
||||||
@@ -85,33 +96,32 @@ fi
|
|||||||
|
|
||||||
vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB"
|
vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB"
|
||||||
|
|
||||||
if ! check_tool_work_ok; then
|
#check tools
|
||||||
|
if check_tool_work_ok; then
|
||||||
|
vtdebug "check tool work ok"
|
||||||
|
else
|
||||||
vterr "Some tools can not run in current system. Please check log.txt for detail."
|
vterr "Some tools can not run in current system. Please check log.txt for detail."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#check mountpoint
|
||||||
grep "^$DISK" /proc/mounts | while read mtline; do
|
grep "^$DISK" /proc/mounts | while read mtline; do
|
||||||
mtpnt=$(echo $mtline | awk '{print $2}')
|
mtpnt=$(echo $mtline | awk '{print $2}')
|
||||||
vtdebug "Trying to umount $mtpnt ..."
|
vtdebug "Trying to umount $mtpnt ..."
|
||||||
umount $mtpnt >/dev/null 2>&1
|
umount $mtpnt >/dev/null 2>&1
|
||||||
done
|
done
|
||||||
|
|
||||||
if swapon -s | grep -q "^${DISK}[0-9]"; then
|
|
||||||
swapon -s | grep "^${DISK}[0-9]" | awk '{print $1}' | while read line; do
|
|
||||||
vtdebug "Trying to swapoff $line ..."
|
|
||||||
swapoff $line
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if grep "$DISK" /proc/mounts; then
|
if grep "$DISK" /proc/mounts; then
|
||||||
vterr "$DISK is already mounted, please umount it first!"
|
vterr "$DISK is already mounted, please umount it first!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if swapon -s | grep -q "^${DISK}[0-9]"; then
|
#check swap partition
|
||||||
vterr "$DISK is used as swap, please swapoff it first!"
|
if swapon --help 2>&1 | grep -q '^ \-s,'; then
|
||||||
exit 1
|
if swapon -s | grep -q "^${DISK}[0-9]"; then
|
||||||
|
vterr "$DISK is used as swap, please swapoff it first!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +132,8 @@ if [ "$MODE" = "install" ]; then
|
|||||||
if parted -v > /dev/null 2>&1; then
|
if parted -v > /dev/null 2>&1; then
|
||||||
PARTTOOL='parted'
|
PARTTOOL='parted'
|
||||||
else
|
else
|
||||||
vterr "parted is not found in the system, Ventoy can't create new partition."
|
vterr "parted is not found in the system, Ventoy can't create new partitions without it."
|
||||||
|
vterr "You should install \"GNU parted\" first."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -131,7 +142,7 @@ if [ "$MODE" = "install" ]; then
|
|||||||
elif fdisk -v >/dev/null 2>&1; then
|
elif fdisk -v >/dev/null 2>&1; then
|
||||||
PARTTOOL='fdisk'
|
PARTTOOL='fdisk'
|
||||||
else
|
else
|
||||||
vterr "Both parted and fdisk are not found in the system, Ventoy can't create new partition."
|
vterr "Both parted and fdisk are not found in the system, Ventoy can't create new partitions."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -202,7 +213,6 @@ if [ "$MODE" = "install" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
|
if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
|
||||||
vterr "No enough space in disk $DISK"
|
vterr "No enough space in disk $DISK"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -240,7 +250,10 @@ if [ "$MODE" = "install" ]; then
|
|||||||
cluster_sectors=64
|
cluster_sectors=64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$cmd -n ventoy -s $cluster_sectors ${DISK}1
|
PART1=$(get_disk_part_name $DISK 1)
|
||||||
|
PART2=$(get_disk_part_name $DISK 2)
|
||||||
|
|
||||||
|
$cmd -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1}
|
||||||
|
|
||||||
vtinfo "writing data to disk ..."
|
vtinfo "writing data to disk ..."
|
||||||
|
|
||||||
@@ -248,13 +261,13 @@ if [ "$MODE" = "install" ]; then
|
|||||||
|
|
||||||
if [ -n "$VTGPT" ]; then
|
if [ -n "$VTGPT" ]; then
|
||||||
echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
|
echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92
|
||||||
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
|
xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
|
||||||
echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
|
echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
|
||||||
else
|
else
|
||||||
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
|
xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector
|
xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector
|
||||||
|
|
||||||
#disk uuid
|
#disk uuid
|
||||||
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
|
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
|
||||||
@@ -268,7 +281,7 @@ if [ "$MODE" = "install" ]; then
|
|||||||
vtinfo "esp partition processing ..."
|
vtinfo "esp partition processing ..."
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
|
mtpnt=$(grep "^${PART2}" /proc/mounts | awk '{print $2}')
|
||||||
if [ -n "$mtpnt" ]; then
|
if [ -n "$mtpnt" ]; then
|
||||||
umount $mtpnt >/dev/null 2>&1
|
umount $mtpnt >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
@@ -278,12 +291,12 @@ if [ "$MODE" = "install" ]; then
|
|||||||
|
|
||||||
vtdebug "mounting part2 ...."
|
vtdebug "mounting part2 ...."
|
||||||
for tt in 1 2 3; do
|
for tt in 1 2 3; do
|
||||||
if mount ${DISK}2 ./tmp_mnt; then
|
if mount ${PART2} ./tmp_mnt; then
|
||||||
vtdebug "mounting part2 success"
|
vtdebug "mounting part2 success"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
|
mtpnt=$(grep "^${PART2}" /proc/mounts | awk '{print $2}')
|
||||||
if [ -n "$mtpnt" ]; then
|
if [ -n "$mtpnt" ]; then
|
||||||
umount $mtpnt >/dev/null 2>&1
|
umount $mtpnt >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
@@ -336,7 +349,7 @@ else
|
|||||||
|
|
||||||
if [ "$PART1_TYPE" = "EE" ]; then
|
if [ "$PART1_TYPE" = "EE" ]; then
|
||||||
vtdebug "This is GPT partition style ..."
|
vtdebug "This is GPT partition style ..."
|
||||||
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
|
xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34
|
||||||
echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
|
echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none
|
||||||
else
|
else
|
||||||
vtdebug "This is MBR partition style ..."
|
vtdebug "This is MBR partition style ..."
|
||||||
@@ -351,10 +364,10 @@ else
|
|||||||
echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none
|
echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none
|
||||||
echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none
|
echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none
|
||||||
fi
|
fi
|
||||||
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
|
xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
|
xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
|
||||||
|
|
||||||
sync
|
sync
|
||||||
|
|
||||||
@@ -363,7 +376,7 @@ else
|
|||||||
|
|
||||||
vtdebug "mounting part2 ...."
|
vtdebug "mounting part2 ...."
|
||||||
for tt in 1 2 3; do
|
for tt in 1 2 3; do
|
||||||
if mount ${DISK}2 ./tmp_mnt; then
|
if mount ${PART2} ./tmp_mnt; then
|
||||||
vtdebug "mounting part2 success"
|
vtdebug "mounting part2 success"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
@@ -52,7 +52,7 @@ check_tool_work_ok() {
|
|||||||
vtoyfat=vtoyfat_32
|
vtoyfat=vtoyfat_32
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if echo 1 | ./tool/hexdump > /dev/null; then
|
if echo 1 | hexdump > /dev/null; then
|
||||||
vtdebug "hexdump test ok ..."
|
vtdebug "hexdump test ok ..."
|
||||||
else
|
else
|
||||||
vtdebug "hexdump test fail ..."
|
vtdebug "hexdump test fail ..."
|
||||||
@@ -88,6 +88,8 @@ get_disk_part_name() {
|
|||||||
echo ${DISK}p${2}
|
echo ${DISK}p${2}
|
||||||
elif echo $DISK | grep -q "/dev/nvme[0-9][0-9]*n[0-9]"; then
|
elif echo $DISK | grep -q "/dev/nvme[0-9][0-9]*n[0-9]"; then
|
||||||
echo ${DISK}p${2}
|
echo ${DISK}p${2}
|
||||||
|
elif echo $DISK | grep -q "/dev/mmcblk[0-9]"; then
|
||||||
|
echo ${DISK}p${2}
|
||||||
else
|
else
|
||||||
echo ${DISK}${2}
|
echo ${DISK}${2}
|
||||||
fi
|
fi
|
||||||
@@ -263,7 +265,7 @@ w
|
|||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
udevadm trigger >/dev/null 2>&1
|
udevadm trigger --name-match=$DISK >/dev/null 2>&1
|
||||||
partprobe >/dev/null 2>&1
|
partprobe >/dev/null 2>&1
|
||||||
sleep 3
|
sleep 3
|
||||||
echo "Done"
|
echo "Done"
|
||||||
@@ -360,7 +362,7 @@ format_ventoy_disk_gpt() {
|
|||||||
$vtoygpt -f $DISK
|
$vtoygpt -f $DISK
|
||||||
sync
|
sync
|
||||||
|
|
||||||
udevadm trigger >/dev/null 2>&1
|
udevadm trigger --name-match=$DISK >/dev/null 2>&1
|
||||||
partprobe >/dev/null 2>&1
|
partprobe >/dev/null 2>&1
|
||||||
sleep 3
|
sleep 3
|
||||||
echo "Done"
|
echo "Done"
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -25,6 +25,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ventoy.h>
|
#include <ventoy.h>
|
||||||
|
|
||||||
int g_debug = 0;
|
int g_debug = 0;
|
||||||
|
int g_hddmode = 0;
|
||||||
|
int g_bios_disk80 = 0;
|
||||||
char *g_cmdline_copy;
|
char *g_cmdline_copy;
|
||||||
void *g_initrd_addr;
|
void *g_initrd_addr;
|
||||||
size_t g_initrd_len;
|
size_t g_initrd_len;
|
||||||
@@ -55,6 +57,40 @@ uint64 g_fixup_iso9660_secover_tot_secs = 0;
|
|||||||
static struct int13_disk_address __bss16 ( ventoy_address );
|
static struct int13_disk_address __bss16 ( ventoy_address );
|
||||||
#define ventoy_address __use_data16 ( ventoy_address )
|
#define ventoy_address __use_data16 ( ventoy_address )
|
||||||
|
|
||||||
|
static uint64_t ventoy_remap_lba_hdd(uint64_t lba, uint32_t *count)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t max_sectors;
|
||||||
|
ventoy_img_chunk *cur;
|
||||||
|
|
||||||
|
if ((NULL == g_cur_chunk) || (lba < g_cur_chunk->img_start_sector) ||
|
||||||
|
(lba > g_cur_chunk->img_end_sector))
|
||||||
|
{
|
||||||
|
g_cur_chunk = NULL;
|
||||||
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
cur = g_chunk + i;
|
||||||
|
if (lba >= cur->img_start_sector && lba <= cur->img_end_sector)
|
||||||
|
{
|
||||||
|
g_cur_chunk = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_cur_chunk)
|
||||||
|
{
|
||||||
|
max_sectors = g_cur_chunk->img_end_sector - lba + 1;
|
||||||
|
if (*count > max_sectors)
|
||||||
|
{
|
||||||
|
*count = max_sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector);
|
||||||
|
}
|
||||||
|
return lba;
|
||||||
|
}
|
||||||
|
|
||||||
static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count)
|
static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@@ -92,6 +128,72 @@ static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count)
|
|||||||
return lba;
|
return lba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ventoy_vdisk_read_real_hdd(uint64_t lba, unsigned int count, unsigned long buffer)
|
||||||
|
{
|
||||||
|
uint32_t left = 0;
|
||||||
|
uint32_t readcount = 0;
|
||||||
|
uint32_t tmpcount = 0;
|
||||||
|
uint16_t status = 0;
|
||||||
|
uint64_t curlba = 0;
|
||||||
|
uint64_t maplba = 0;
|
||||||
|
unsigned long phyaddr;
|
||||||
|
|
||||||
|
curlba = lba;
|
||||||
|
left = count;
|
||||||
|
|
||||||
|
#if VTOY_DEBUG
|
||||||
|
printf("ventoy_vdisk_read_real_hdd: %llu %u\n", lba, count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (left > 0)
|
||||||
|
{
|
||||||
|
readcount = left;
|
||||||
|
maplba = ventoy_remap_lba_hdd(curlba, &readcount);
|
||||||
|
|
||||||
|
tmpcount = readcount;
|
||||||
|
|
||||||
|
phyaddr = user_to_phys(buffer, 0);
|
||||||
|
|
||||||
|
while (tmpcount > 0)
|
||||||
|
{
|
||||||
|
/* Use INT 13, 42 to read the data from real disk */
|
||||||
|
ventoy_address.lba = maplba;
|
||||||
|
ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4);
|
||||||
|
ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F);
|
||||||
|
|
||||||
|
if (tmpcount >= 64) /* max sectors per transmit */
|
||||||
|
{
|
||||||
|
ventoy_address.count = 64;
|
||||||
|
tmpcount -= 64;
|
||||||
|
maplba += 64;
|
||||||
|
phyaddr += 32768;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ventoy_address.count = tmpcount;
|
||||||
|
tmpcount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
|
||||||
|
"sti\n\t"
|
||||||
|
"int $0x13\n\t"
|
||||||
|
"sti\n\t" /* BIOS bugs */
|
||||||
|
"jc 1f\n\t"
|
||||||
|
"xorw %%ax, %%ax\n\t"
|
||||||
|
"\n1:\n\t" )
|
||||||
|
: "=a" ( status )
|
||||||
|
: "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ),
|
||||||
|
"S" ( __from_data16 ( &ventoy_address ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
curlba += readcount;
|
||||||
|
left -= readcount;
|
||||||
|
buffer += (readcount * 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned long buffer)
|
static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned long buffer)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
@@ -297,6 +399,13 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun
|
|||||||
|
|
||||||
ix86 = (struct i386_all_regs *)sandev->x86_regptr;
|
ix86 = (struct i386_all_regs *)sandev->x86_regptr;
|
||||||
|
|
||||||
|
if (g_hddmode)
|
||||||
|
{
|
||||||
|
ventoy_vdisk_read_real_hdd(lba, count, buffer);
|
||||||
|
ix86->regs.dl = sandev->drive;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Workaround for SSTR PE loader error */
|
/* Workaround for SSTR PE loader error */
|
||||||
if (g_fixup_iso9660_secover_start)
|
if (g_fixup_iso9660_secover_start)
|
||||||
{
|
{
|
||||||
@@ -441,9 +550,12 @@ static void ventoy_dump_chain(ventoy_chain_head *chain)
|
|||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint8_t chksum = 0;
|
uint8_t chksum = 0;
|
||||||
uint8_t *guid;
|
uint8_t *guid;
|
||||||
|
uint8_t *sig;
|
||||||
uint8_t *vtoy_reserve;
|
uint8_t *vtoy_reserve;
|
||||||
|
|
||||||
guid = chain->os_param.vtoy_disk_guid;
|
guid = chain->os_param.vtoy_disk_guid;
|
||||||
|
sig = chain->os_param.vtoy_disk_signature;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(ventoy_os_param); i++)
|
for (i = 0; i < sizeof(ventoy_os_param); i++)
|
||||||
{
|
{
|
||||||
chksum += *((uint8_t *)(&(chain->os_param)) + i);
|
chksum += *((uint8_t *)(&(chain->os_param)) + i);
|
||||||
@@ -457,6 +569,7 @@ static void ventoy_dump_chain(ventoy_chain_head *chain)
|
|||||||
|
|
||||||
printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
|
printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
|
||||||
printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]);
|
printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]);
|
||||||
|
printf("os_param->vtoy_disk_signature=%02x%02x%02x%02x\n", sig[0], sig[1], sig[2], sig[3]);
|
||||||
printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size);
|
printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size);
|
||||||
printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id);
|
printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id);
|
||||||
printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type);
|
printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type);
|
||||||
@@ -530,19 +643,33 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
memcpy(&location->guid, ¶m->guid, sizeof(ventoy_guid));
|
||||||
location->image_sector_size = 2048;
|
location->image_sector_size = g_hddmode ? 512 : 2048;
|
||||||
location->disk_sector_size = g_chain->disk_sector_size;
|
location->disk_sector_size = g_chain->disk_sector_size;
|
||||||
location->region_count = g_img_chunk_num;
|
location->region_count = g_img_chunk_num;
|
||||||
|
|
||||||
region = location->regions;
|
region = location->regions;
|
||||||
|
|
||||||
for (i = 0; i < g_img_chunk_num; i++)
|
if (g_hddmode)
|
||||||
{
|
{
|
||||||
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
region->image_start_sector = chunk->img_start_sector;
|
{
|
||||||
region->disk_start_sector = chunk->disk_start_sector;
|
region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
|
||||||
region++;
|
region->image_start_sector = chunk->img_start_sector * 4;
|
||||||
chunk++;
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
|
||||||
|
region->image_start_sector = chunk->img_start_sector;
|
||||||
|
region->disk_start_sector = chunk->disk_start_sector;
|
||||||
|
region++;
|
||||||
|
chunk++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -553,6 +680,7 @@ int ventoy_boot_vdisk(void *data)
|
|||||||
uint8_t chksum = 0;
|
uint8_t chksum = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int drive;
|
unsigned int drive;
|
||||||
|
ventoy_img_chunk *cur;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
@@ -562,8 +690,19 @@ int ventoy_boot_vdisk(void *data)
|
|||||||
{
|
{
|
||||||
g_debug = 1;
|
g_debug = 1;
|
||||||
printf("### ventoy chain boot begin... ###\n");
|
printf("### ventoy chain boot begin... ###\n");
|
||||||
|
printf("cmdline: <%s>\n", g_cmdline_copy);
|
||||||
ventoy_debug_pause();
|
ventoy_debug_pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strstr(g_cmdline_copy, "sector512"))
|
||||||
|
{
|
||||||
|
g_hddmode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(g_cmdline_copy, "bios80"))
|
||||||
|
{
|
||||||
|
g_bios_disk80 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
g_chain = (ventoy_chain_head *)g_initrd_addr;
|
g_chain = (ventoy_chain_head *)g_initrd_addr;
|
||||||
g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
|
g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
|
||||||
@@ -601,6 +740,16 @@ int ventoy_boot_vdisk(void *data)
|
|||||||
ventoy_dump_chain(g_chain);
|
ventoy_dump_chain(g_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_hddmode)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_img_chunk_num; i++)
|
||||||
|
{
|
||||||
|
cur = g_chunk + i;
|
||||||
|
cur->img_start_sector *= 4;
|
||||||
|
cur->img_end_sector = cur->img_end_sector * 4 + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
drive = ventoy_int13_hook(g_chain);
|
drive = ventoy_int13_hook(g_chain);
|
||||||
|
|
||||||
if (g_debug)
|
if (g_debug)
|
||||||
|
@@ -1051,6 +1051,10 @@ static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
|
|||||||
/* We simulate a cdrom, so no need to sync hd drive number */
|
/* We simulate a cdrom, so no need to sync hd drive number */
|
||||||
//int13_check_num_drives();
|
//int13_check_num_drives();
|
||||||
|
|
||||||
|
#if VTOY_DEBUG
|
||||||
|
printf("int13 0x%x 0x%x\n", bios_drive, command); sleep(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bios_drive == VENTOY_BIOS_FAKE_DRIVE)
|
if (bios_drive == VENTOY_BIOS_FAKE_DRIVE)
|
||||||
{
|
{
|
||||||
ix86->regs.dl = g_sandev->exdrive;
|
ix86->regs.dl = g_sandev->exdrive;
|
||||||
@@ -1255,39 +1259,15 @@ static void int13_hook_vector ( void ) {
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int int13_load_mbr ( unsigned int drive, struct segoff *address ) {
|
static int int13_load_mbr ( unsigned int drive, struct segoff *address ) {
|
||||||
uint16_t status;
|
|
||||||
int discard_b, discard_c, discard_d;
|
|
||||||
uint16_t magic;
|
uint16_t magic;
|
||||||
|
|
||||||
/* Use INT 13, 02 to read the MBR */
|
address->segment = 0;
|
||||||
address->segment = 0;
|
address->offset = 0x7c00;
|
||||||
address->offset = 0x7c00;
|
copy_to_real(address->segment, address->offset, g_sandev->boot_catalog_sector, 512);
|
||||||
__asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
|
|
||||||
"pushl %%ebx\n\t"
|
|
||||||
"popw %%bx\n\t"
|
|
||||||
"popw %%es\n\t"
|
|
||||||
"stc\n\t"
|
|
||||||
"sti\n\t"
|
|
||||||
"int $0x13\n\t"
|
|
||||||
"sti\n\t" /* BIOS bugs */
|
|
||||||
"jc 1f\n\t"
|
|
||||||
"xorw %%ax, %%ax\n\t"
|
|
||||||
"\n1:\n\t"
|
|
||||||
"popw %%es\n\t" )
|
|
||||||
: "=a" ( status ), "=b" ( discard_b ),
|
|
||||||
"=c" ( discard_c ), "=d" ( discard_d )
|
|
||||||
: "a" ( 0x0201 ), "b" ( *address ),
|
|
||||||
"c" ( 1 ), "d" ( drive ) );
|
|
||||||
if ( status ) {
|
|
||||||
DBG ( "INT13 drive %02x could not read MBR (status %04x)\n",
|
|
||||||
drive, status );
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check magic signature */
|
/* Check magic signature */
|
||||||
get_real ( magic, address->segment,
|
get_real ( magic, address->segment, (address->offset + offsetof ( struct master_boot_record, magic ) ) );
|
||||||
( address->offset +
|
|
||||||
offsetof ( struct master_boot_record, magic ) ) );
|
|
||||||
if ( magic != INT13_MBR_MAGIC ) {
|
if ( magic != INT13_MBR_MAGIC ) {
|
||||||
DBG ( "INT13 drive %02x does not contain a valid MBR\n",
|
DBG ( "INT13 drive %02x does not contain a valid MBR\n",
|
||||||
drive );
|
drive );
|
||||||
@@ -1443,8 +1423,14 @@ unsigned int ventoy_int13_hook (ventoy_chain_head *chain)
|
|||||||
/* hook will copy num_drives to dl when int13 08 was called, so must initialize it's value */
|
/* hook will copy num_drives to dl when int13 08 was called, so must initialize it's value */
|
||||||
get_real(num_drives, BDA_SEG, BDA_NUM_DRIVES);
|
get_real(num_drives, BDA_SEG, BDA_NUM_DRIVES);
|
||||||
|
|
||||||
//natural_drive = num_drives | 0x80;
|
if (g_hddmode)
|
||||||
natural_drive = 0xE0; /* just set a cdrom drive number 224 */
|
{
|
||||||
|
natural_drive = g_bios_disk80 ? 0x80 : (num_drives | 0x80);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
natural_drive = 0xE0; /* just set a cdrom drive number 224 */
|
||||||
|
}
|
||||||
|
|
||||||
if (chain->disk_drive >= 0x80 && chain->drive_map >= 0x80)
|
if (chain->disk_drive >= 0x80 && chain->drive_map >= 0x80)
|
||||||
{
|
{
|
||||||
@@ -1456,8 +1442,8 @@ unsigned int ventoy_int13_hook (ventoy_chain_head *chain)
|
|||||||
g_sandev = zalloc(sizeof(struct san_device) + sizeof(struct int13_data));
|
g_sandev = zalloc(sizeof(struct san_device) + sizeof(struct int13_data));
|
||||||
g_sandev->priv = int13 = (struct int13_data *)(g_sandev + 1);
|
g_sandev->priv = int13 = (struct int13_data *)(g_sandev + 1);
|
||||||
g_sandev->drive = int13->natural_drive = natural_drive;
|
g_sandev->drive = int13->natural_drive = natural_drive;
|
||||||
g_sandev->is_cdrom = 1;
|
g_sandev->is_cdrom = g_hddmode ? 0 : 1;
|
||||||
g_sandev->blksize_shift = 2;
|
g_sandev->blksize_shift = g_hddmode ? 0 : 2;
|
||||||
g_sandev->capacity.blksize = 512;
|
g_sandev->capacity.blksize = 512;
|
||||||
g_sandev->capacity.blocks = chain->virt_img_size_in_bytes / 512;
|
g_sandev->capacity.blocks = chain->virt_img_size_in_bytes / 512;
|
||||||
g_sandev->exdrive = chain->disk_drive;
|
g_sandev->exdrive = chain->disk_drive;
|
||||||
@@ -1521,9 +1507,20 @@ int ventoy_int13_boot ( unsigned int drive, void *imginfo, const char *cmdline)
|
|||||||
struct ibft_table *ibft = NULL;
|
struct ibft_table *ibft = NULL;
|
||||||
|
|
||||||
/* Look for a usable boot sector */
|
/* Look for a usable boot sector */
|
||||||
if ( ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) &&
|
if (g_hddmode)
|
||||||
( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ))
|
{
|
||||||
|
if ((rc = int13_load_mbr(drive, &address)) != 0)
|
||||||
|
{
|
||||||
|
printf("int13_load_mbr %d\n", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) &&
|
||||||
|
( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ))
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
if (imginfo)
|
if (imginfo)
|
||||||
{
|
{
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
//#define VTOY_DEBUG 1
|
||||||
|
|
||||||
#define grub_uint64_t uint64_t
|
#define grub_uint64_t uint64_t
|
||||||
#define grub_uint32_t uint32_t
|
#define grub_uint32_t uint32_t
|
||||||
#define grub_uint16_t uint16_t
|
#define grub_uint16_t uint16_t
|
||||||
@@ -43,7 +45,7 @@ typedef struct ventoy_image_location
|
|||||||
{
|
{
|
||||||
ventoy_guid guid;
|
ventoy_guid guid;
|
||||||
|
|
||||||
/* image sector size, currently this value is always 2048 */
|
/* image sector size, 2048/512 */
|
||||||
grub_uint32_t image_sector_size;
|
grub_uint32_t image_sector_size;
|
||||||
|
|
||||||
/* disk sector size, normally the value is 512 */
|
/* disk sector size, normally the value is 512 */
|
||||||
@@ -86,7 +88,9 @@ typedef struct ventoy_os_param
|
|||||||
|
|
||||||
grub_uint64_t vtoy_reserved[4]; // Internal use by ventoy
|
grub_uint64_t vtoy_reserved[4]; // Internal use by ventoy
|
||||||
|
|
||||||
grub_uint8_t reserved[31];
|
grub_uint8_t vtoy_disk_signature[4];
|
||||||
|
|
||||||
|
grub_uint8_t reserved[27];
|
||||||
}ventoy_os_param;
|
}ventoy_os_param;
|
||||||
|
|
||||||
typedef struct ventoy_iso9660_override
|
typedef struct ventoy_iso9660_override
|
||||||
@@ -182,6 +186,8 @@ typedef struct ventoy_sector_flag
|
|||||||
#define VENTOY_BOOT_FIXBIN_DRIVE 0xFD
|
#define VENTOY_BOOT_FIXBIN_DRIVE 0xFD
|
||||||
|
|
||||||
extern int g_debug;
|
extern int g_debug;
|
||||||
|
extern int g_hddmode;
|
||||||
|
extern int g_bios_disk80;
|
||||||
extern char *g_cmdline_copy;
|
extern char *g_cmdline_copy;
|
||||||
extern void *g_initrd_addr;
|
extern void *g_initrd_addr;
|
||||||
extern size_t g_initrd_len;
|
extern size_t g_initrd_len;
|
||||||
|
Binary file not shown.
@@ -20,7 +20,7 @@ get_disk_size() {
|
|||||||
enum_disk() {
|
enum_disk() {
|
||||||
id=1
|
id=1
|
||||||
rm -f /device.list
|
rm -f /device.list
|
||||||
ls /sys/block/ | grep 'd[a-z]' | while read dev; do
|
ls /sys/block/ | egrep 'd[a-z]|nvme|mmc' | while read dev; do
|
||||||
if ! [ -b /dev/$dev ]; then
|
if ! [ -b /dev/$dev ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@@ -145,7 +145,7 @@ ventoy_configuration() {
|
|||||||
elif [ "$Answer" = "1" ]; then
|
elif [ "$Answer" = "1" ]; then
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Please input the preserve space in MB: " Answer
|
read -p "Please input the preserve space in MB: " Answer
|
||||||
if echo $Answer | grep -q "^[1-9][0-9]*$"; then
|
if echo $Answer | grep -q "^[0-9][0-9]*$"; then
|
||||||
echo $Answer > /preserve.txt
|
echo $Answer > /preserve.txt
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
28
README.md
28
README.md
@@ -10,36 +10,38 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4 align="left">
|
<h4 align="left">
|
||||||
Ventoy is an open source tool to create bootable USB drive for ISO/WIM/IMG/EFI files. <br/>
|
Ventoy is an open source tool to create bootable USB drive for ISO/WIM/IMG/VHD(x)/EFI files. <br/>
|
||||||
With ventoy, you don't need to format the disk over and over, you just need to copy the image files to the USB drive and boot it.
|
With ventoy, you don't need to format the disk over and over, you just need to copy the image files to the USB drive and boot it.
|
||||||
You can copy many iso files at a time and ventoy will give you a boot menu to select them. <br/>
|
You can copy many iso files at a time and ventoy will give you a boot menu to select them. <br/>
|
||||||
Both Legacy BIOS and UEFI are supported in the same way.<br/>
|
Both Legacy BIOS and UEFI are supported in the same way.<br/>
|
||||||
Both MBR and GPT partition style are supported in the same way.<br/>
|
Both MBR and GPT partition style are supported in the same way.<br/>
|
||||||
Most type of OS supported(Windows/WinPE/Linux/Unix/Vmware/Xen...), 550+ ISO files are tested. <br/>
|
Most type of OS supported(Windows/WinPE/Linux/Unix/Vmware/Xen...) <br/>
|
||||||
A "Ventoy Compatible" concept is introduced by ventoy, which can help to support any ISO file.
|
560+ ISO files are tested. 90%+ distros in distrowatch.com supported. <br/>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
* 100% open source
|
* 100% open source
|
||||||
* Simple to use
|
* Simple to use
|
||||||
* Fast (limited only by the speed of copying iso file)
|
* Fast (limited only by the speed of copying iso file)
|
||||||
* Directly boot from iso/wim/img file, no extraction needed
|
* Can be installed in USB/Local Disk/SSD/NVMe/SD Card
|
||||||
* Legacy + UEFI supported in the same way
|
* Directly boot from ISO/WIM/IMG/VHD(x)/EFI files, no extraction needed
|
||||||
* UEFI Secure Boot supported (since 1.0.07+)
|
* No need to be continuous in disk for ISO/IMG files
|
||||||
* Persistence supported (since 1.0.11+)
|
|
||||||
* MBR and GPT partition style supported (1.0.15+)
|
* MBR and GPT partition style supported (1.0.15+)
|
||||||
* WIM files boot supported (Legacy + UEFI) (1.0.12+)
|
* Legacy + UEFI supported in the same way
|
||||||
* IMG files boot supported (Legacy + UEFI) (1.0.19+)
|
* UEFI Secure Boot supported (1.0.07+)
|
||||||
* Auto installation supported (1.0.09+)
|
* Persistence supported (1.0.11+)
|
||||||
* File injection supported (1.0.16+)
|
* Windows/Linux auto installation supported (1.0.09+)
|
||||||
* ISO files larger than 4GB supported
|
* ISO files larger than 4GB supported
|
||||||
* Native boot menu style for Legacy & UEFI
|
* Native boot menu style for Legacy & UEFI
|
||||||
* Most type of OS supported(Windows/WinPE/Linux/Unix/Vmware/Xen...), 550+ iso files tested
|
* Most type of OS supported, 560+ iso files tested
|
||||||
|
* Linux vDisk boot supported
|
||||||
* Not only boot but also complete installation process
|
* Not only boot but also complete installation process
|
||||||
* ISO files can be listed in List mode/TreeView mode
|
* ISO files can be listed in List mode/TreeView mode
|
||||||
* "Ventoy Compatible" concept
|
* "Ventoy Compatible" concept
|
||||||
* Plugin Framework
|
* Plugin Framework
|
||||||
* Menu Alias/Menu Style/Customized Menu supported
|
* Injection files to runtime enviroment
|
||||||
|
* Boot configuration file dynamically replacement
|
||||||
|
* Highly customizable theme and menu
|
||||||
* USB drive write-protected support
|
* USB drive write-protected support
|
||||||
* USB normal use unaffected
|
* USB normal use unaffected
|
||||||
* Data nondestructive during version upgrade
|
* Data nondestructive during version upgrade
|
||||||
|
@@ -507,9 +507,18 @@ static int vtoydm_print_linear_table(const char *img_map_file, const char *diskn
|
|||||||
(sector_start << 2), disk_sector_num,
|
(sector_start << 2), disk_sector_num,
|
||||||
diskname, (unsigned long long)chunk[i].disk_start_sector);
|
diskname, (unsigned long long)chunk[i].disk_start_sector);
|
||||||
#else
|
#else
|
||||||
printf("%u %u linear %s1 %llu\n",
|
if (strstr(diskname, "nvme") || strstr(diskname, "mmc"))
|
||||||
|
{
|
||||||
|
printf("%u %u linear %sp1 %llu\n",
|
||||||
(sector_start << 2), disk_sector_num,
|
(sector_start << 2), disk_sector_num,
|
||||||
diskname, (unsigned long long)chunk[i].disk_start_sector - 2048);
|
diskname, (unsigned long long)chunk[i].disk_start_sector - 2048);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%u %u linear %s1 %llu\n",
|
||||||
|
(sector_start << 2), disk_sector_num,
|
||||||
|
diskname, (unsigned long long)chunk[i].disk_start_sector - 2048);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -120,7 +120,9 @@ typedef struct ventoy_os_param
|
|||||||
|
|
||||||
uint64_t vtoy_reserved[4]; // Internal use by ventoy
|
uint64_t vtoy_reserved[4]; // Internal use by ventoy
|
||||||
|
|
||||||
uint8_t reserved[31];
|
uint8_t vtoy_disk_signature[4];
|
||||||
|
|
||||||
|
uint8_t reserved[27];
|
||||||
}ventoy_os_param;
|
}ventoy_os_param;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
@@ -218,6 +220,11 @@ static void vtoy_dump_os_param(ventoy_os_param *param)
|
|||||||
printf("param->vtoy_disk_guid = %02x %02x %02x %02x\n",
|
printf("param->vtoy_disk_guid = %02x %02x %02x %02x\n",
|
||||||
param->vtoy_disk_guid[0], param->vtoy_disk_guid[1],
|
param->vtoy_disk_guid[0], param->vtoy_disk_guid[1],
|
||||||
param->vtoy_disk_guid[2], param->vtoy_disk_guid[3]);
|
param->vtoy_disk_guid[2], param->vtoy_disk_guid[3]);
|
||||||
|
|
||||||
|
printf("param->vtoy_disk_signature = %02x %02x %02x %02x\n",
|
||||||
|
param->vtoy_disk_signature[0], param->vtoy_disk_signature[1],
|
||||||
|
param->vtoy_disk_signature[2], param->vtoy_disk_signature[3]);
|
||||||
|
|
||||||
printf("param->vtoy_disk_size = %llu\n", (unsigned long long)param->vtoy_disk_size);
|
printf("param->vtoy_disk_size = %llu\n", (unsigned long long)param->vtoy_disk_size);
|
||||||
printf("param->vtoy_disk_part_id = %u\n", param->vtoy_disk_part_id);
|
printf("param->vtoy_disk_part_id = %u\n", param->vtoy_disk_part_id);
|
||||||
printf("param->vtoy_disk_part_type = %u\n", param->vtoy_disk_part_type);
|
printf("param->vtoy_disk_part_type = %u\n", param->vtoy_disk_part_type);
|
||||||
@@ -231,7 +238,7 @@ static void vtoy_dump_os_param(ventoy_os_param *param)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid)
|
static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid, uint8_t *vtsig)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
@@ -244,6 +251,9 @@ static int vtoy_get_disk_guid(const char *diskname, uint8_t *vtguid)
|
|||||||
{
|
{
|
||||||
lseek(fd, 0x180, SEEK_SET);
|
lseek(fd, 0x180, SEEK_SET);
|
||||||
read(fd, vtguid, 16);
|
read(fd, vtguid, 16);
|
||||||
|
|
||||||
|
lseek(fd, 0x1b8, SEEK_SET);
|
||||||
|
read(fd, vtsig, 4);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
debug("GUID for %s: <", devdisk);
|
debug("GUID for %s: <", devdisk);
|
||||||
@@ -380,13 +390,14 @@ static int vtoy_find_disk_by_size(unsigned long long size, char *diskname)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vtoy_find_disk_by_guid(uint8_t *guid, char *diskname)
|
static int vtoy_find_disk_by_guid(ventoy_os_param *param, char *diskname)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
DIR* dir = NULL;
|
DIR* dir = NULL;
|
||||||
struct dirent* p = NULL;
|
struct dirent* p = NULL;
|
||||||
uint8_t vtguid[16];
|
uint8_t vtguid[16];
|
||||||
|
uint8_t vtsig[16];
|
||||||
|
|
||||||
dir = opendir("/sys/block");
|
dir = opendir("/sys/block");
|
||||||
if (!dir)
|
if (!dir)
|
||||||
@@ -403,8 +414,9 @@ static int vtoy_find_disk_by_guid(uint8_t *guid, char *diskname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(vtguid, 0, sizeof(vtguid));
|
memset(vtguid, 0, sizeof(vtguid));
|
||||||
rc = vtoy_get_disk_guid(p->d_name, vtguid);
|
rc = vtoy_get_disk_guid(p->d_name, vtguid, vtsig);
|
||||||
if (rc == 0 && memcmp(vtguid, guid, 16) == 0)
|
if (rc == 0 && memcmp(vtguid, param->vtoy_disk_guid, 16) == 0 &&
|
||||||
|
memcmp(vtsig, param->vtoy_disk_signature, 4) == 0)
|
||||||
{
|
{
|
||||||
sprintf(diskname, "%s", p->d_name);
|
sprintf(diskname, "%s", p->d_name);
|
||||||
count++;
|
count++;
|
||||||
@@ -430,11 +442,11 @@ static int vtoy_print_os_param(ventoy_os_param *param, char *diskname)
|
|||||||
cnt = vtoy_find_disk_by_size(param->vtoy_disk_size, diskname);
|
cnt = vtoy_find_disk_by_size(param->vtoy_disk_size, diskname);
|
||||||
if (cnt > 1)
|
if (cnt > 1)
|
||||||
{
|
{
|
||||||
cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname);
|
cnt = vtoy_find_disk_by_guid(param, diskname);
|
||||||
}
|
}
|
||||||
else if (cnt == 0)
|
else if (cnt == 0)
|
||||||
{
|
{
|
||||||
cnt = vtoy_find_disk_by_guid(param->vtoy_disk_guid, diskname);
|
cnt = vtoy_find_disk_by_guid(param, diskname);
|
||||||
debug("find 0 disk by size, try with guid cnt=%d...\n", cnt);
|
debug("find 0 disk by size, try with guid cnt=%d...\n", cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,17 +474,19 @@ static int vtoy_check_device(ventoy_os_param *param, const char *device)
|
|||||||
{
|
{
|
||||||
unsigned long long size;
|
unsigned long long size;
|
||||||
uint8_t vtguid[16] = {0};
|
uint8_t vtguid[16] = {0};
|
||||||
|
uint8_t vtsig[4] = {0};
|
||||||
|
|
||||||
debug("vtoy_check_device for <%s>\n", device);
|
debug("vtoy_check_device for <%s>\n", device);
|
||||||
|
|
||||||
size = vtoy_get_disk_size_in_byte(device);
|
size = vtoy_get_disk_size_in_byte(device);
|
||||||
vtoy_get_disk_guid(device, vtguid);
|
vtoy_get_disk_guid(device, vtguid, vtsig);
|
||||||
|
|
||||||
debug("param->vtoy_disk_size=%llu size=%llu\n",
|
debug("param->vtoy_disk_size=%llu size=%llu\n",
|
||||||
(unsigned long long)param->vtoy_disk_size, (unsigned long long)size);
|
(unsigned long long)param->vtoy_disk_size, (unsigned long long)size);
|
||||||
|
|
||||||
if ((param->vtoy_disk_size == size || param->vtoy_disk_size == size + 512) &&
|
if ((param->vtoy_disk_size == size || param->vtoy_disk_size == size + 512) &&
|
||||||
memcmp(vtguid, param->vtoy_disk_guid, 16) == 0)
|
memcmp(vtguid, param->vtoy_disk_guid, 16) == 0 &&
|
||||||
|
memcmp(vtsig, param->vtoy_disk_signature, 4) == 0)
|
||||||
{
|
{
|
||||||
debug("<%s> is right ventoy disk\n", device);
|
debug("<%s> is right ventoy disk\n", device);
|
||||||
return 0;
|
return 0;
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user