Compare commits

...

38 Commits

Author SHA1 Message Date
longpanda
e8d17f9bb1 1.0.28 release 2020-11-14 12:29:01 +08:00
longpanda
2283c3e8b0 update README.md 2020-11-13 22:15:24 +08:00
longpanda
8bbd5a14a3 最近收到一些特殊的错误报告,最后证明是非标准的Ventoy环境的原因。尤其是单分区下环境下使用 Ventoy 。
虽然 Ventoy 显示了 Unofficial 的标注信息,但是用户并不会关心,仍然会认为是 Ventoy 的问题。

Ventoy 从一开始就是一个整体的设计,并没有考虑过集成在其他bootloader或分区环境中。
Ventoy 的验证和后续新功能开发也都不会考虑这种非标准的使用方式。

因此,我决定禁止 Ventoy 在非标准环境下的使用,并且不再接受放开检查的请求。

当然,这个只是Ventoy的默认行为。Ventoy仍然是100%开源的,如果你希望把Ventoy应用在自己的环境中,你可以fork一个分支,然后修改源代码实现。
2020-11-13 16:39:15 +08:00
Victor B
f7d7db6a18 Fix typo in BuildVentoyFromSource.txt (#580) 2020-11-09 15:25:19 +08:00
longpanda
147a23c9dd 1.0.27 release 2020-10-31 19:06:30 +08:00
longpanda
062c71b972 fix a bug about VTOY_DEFAULT_IMAGE in treeview mode issue #555 2020-10-31 13:38:13 +08:00
longpanda
78ab7a0759 1.0.26 release 2020-10-24 06:26:57 +08:00
longpanda
3ebd58c9df support original order in image_list plugin 2020-10-22 09:34:46 +08:00
longpanda
ce6d379564 1.0.25 release 2020-10-21 20:33:15 +08:00
longpanda
40fdfa66b9 Optimization for Linux vDisk boot in Legacy BIOS mode 2020-10-21 17:45:44 +08:00
longpanda
9ddee7394d support different themes for Legacy BIOS mode and UEFI mode 2020-10-21 17:15:31 +08:00
longpanda
c9b316a757 Fix bug for VTOY_DEFAULT_IMAGE in TreeView mode when VTOY_DEFAULT_SEARCH_ROOT was set. 2020-10-21 13:17:29 +08:00
longpanda
1ba23bcdff add image_list plugin 2020-10-21 10:23:58 +08:00
longpanda
6630ab3585 1.0.24 release 2020-10-17 15:56:54 +08:00
longpanda
c0d478c2dd 1.0.23 release 2020-10-16 20:26:24 +08:00
longpanda
0217c5a923 fix issue #521
blackarch boot failed
2020-10-15 17:50:22 +08:00
longpanda
97312d351e fix issue #516
Arch 2020.10.1 iso boot failed in UEFI mode.
2020-10-09 19:57:35 +08:00
David P
906dc4cd41 fix Parabola EFI booting (#508) 2020-10-09 09:41:04 +08:00
longpanda
82a8b59bc7 fix issue #512
show file with name .iso
2020-10-08 17:13:40 +08:00
longpanda
b53e1fb8a8 1.0.22 release 2020-09-27 22:20:37 +08:00
longpanda
84abffc424 theme 2020-09-27 17:31:02 +08:00
longpanda
bf4e014023 linux raw boot 2020-09-27 17:23:59 +08:00
longpanda
4f840ed673 Merge branch 'master' of https://github.com/ventoy/Ventoy 2020-09-26 00:05:27 +08:00
longpanda
d02f184a8d add support for linux vdisk(vhd/vdi/raw) 2020-09-26 00:04:56 +08:00
longpanda
774e38928f update VentoyWorker.sh for nvme 2020-09-18 11:49:18 +08:00
David P
0faba673a5 fix Parabola systemd-boot loader (#473) 2020-09-14 09:56:12 +08:00
longpanda
3c649b281f update README.md 2020-09-13 14:47:44 +08:00
longpanda
5f409a1208 Fix a bug with error message null src bitmap in grub_video_bitmap_create_scaled 2020-09-13 14:43:57 +08:00
longpanda
9eb334d99a 1.0.21 release 2020-09-12 22:31:21 +08:00
longpanda
260a3269b7 Merge branch 'master' of https://github.com/ventoy/Ventoy
# Conflicts:
#	INSTALL/ventoy/ventoy.cpio
2020-09-12 02:49:39 +08:00
longpanda
a287bf8907 vhd boot
live cd
fix bug
2020-09-12 02:46:44 +08:00
longpanda
48a1b80be0 update 2020-09-03 16:45:18 +08:00
longpanda
b9ef72fbe9 Fix issue #456 2020-09-03 16:43:21 +08:00
longpanda
390507fff7 Fix issue #456 2020-09-03 16:40:26 +08:00
longpanda
a29bdfbc3c LiveCD 2020-09-03 07:46:36 +08:00
longpanda
21735f92d6 Merge branch 'master' of https://github.com/ventoy/Ventoy 2020-09-02 19:29:43 +08:00
longpanda
9a8d4d0227 update 2020-09-02 19:29:19 +08:00
longpanda
6ebe77792c Update README.md 2020-08-30 21:59:09 +08:00
107 changed files with 5404 additions and 329 deletions

View File

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

View File

@@ -273,19 +273,33 @@ static int ventoy_update_image_location(ventoy_os_param *param)
} }
CopyMem(&location->guid, &param->guid, sizeof(ventoy_guid)); CopyMem(&location->guid, &param->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;
@@ -378,6 +392,36 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID)
return Status; return Status;
} }
#if (VENTOY_DEVICE_WARN != 0)
STATIC VOID ventoy_warn_invalid_device(VOID)
{
STATIC BOOLEAN flag = FALSE;
if (flag)
{
return;
}
flag = TRUE;
gST->ConOut->ClearScreen(gST->ConOut);
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, 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"\r\n\r\nWill exit after 10 seconds ...... ");
sleep(10);
}
#else
STATIC VOID ventoy_warn_invalid_device(VOID)
{
}
#endif
STATIC EFI_STATUS EFIAPI ventoy_load_image STATIC EFI_STATUS EFIAPI ventoy_load_image
( (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
@@ -420,6 +464,7 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
UINTN i = 0; UINTN i = 0;
UINTN Count = 0; UINTN Count = 0;
UINT64 DiskSize = 0; UINT64 DiskSize = 0;
MBR_HEAD *pMBR = NULL;
UINT8 *pBuffer = NULL; UINT8 *pBuffer = NULL;
EFI_HANDLE *Handles; EFI_HANDLE *Handles;
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
@@ -463,6 +508,18 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0) if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0)
{ {
pMBR = (MBR_HEAD *)pBuffer;
if (pMBR->PartTbl[0].FsFlag != 0xEE)
{
if (pMBR->PartTbl[0].StartSectorId != 2048 ||
pMBR->PartTbl[1].SectorCount != 65536 ||
pMBR->PartTbl[1].StartSectorId != pMBR->PartTbl[0].StartSectorId + pMBR->PartTbl[0].SectorCount)
{
debug("Failed to check disk part table");
ventoy_warn_invalid_device();
}
}
gBlockData.RawBlockIoHandle = Handles[i]; gBlockData.RawBlockIoHandle = Handles[i];
gBlockData.pRawBlockIo = pBlockIo; gBlockData.pRawBlockIo = pBlockIo;
gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
@@ -582,6 +639,7 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
UINT32 old_cnt = 0; UINT32 old_cnt = 0;
UINTN size = 0; UINTN size = 0;
UINT8 chksum = 0; UINT8 chksum = 0;
const char *pEnv = NULL;
CHAR16 *pPos = NULL; CHAR16 *pPos = NULL;
CHAR16 *pCmdLine = NULL; CHAR16 *pCmdLine = NULL;
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
@@ -649,9 +707,20 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
} }
pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
grub_env_get = pGrubParam->grub_env_get;
grub_env_set = pGrubParam->grub_env_set; grub_env_set = pGrubParam->grub_env_set;
grub_env_get = pGrubParam->grub_env_get;
pEnv = grub_env_get("VTOY_CHKDEV_RESULT_STRING");
if (!pEnv)
{
return EFI_INVALID_PARAMETER;
}
if (pEnv[0] != '0' || pEnv[1] != 0)
{
ventoy_warn_invalid_device();
return EFI_INVALID_PARAMETER;
}
g_file_replace_list = &pGrubParam->file_replace; g_file_replace_list = &pGrubParam->file_replace;
old_cnt = g_file_replace_list->old_file_cnt; old_cnt = g_file_replace_list->old_file_cnt;
debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>", debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
@@ -963,7 +1032,11 @@ EFI_STATUS EFIAPI VentoyEfiMain
gST->ConOut->ClearScreen(gST->ConOut); gST->ConOut->ClearScreen(gST->ConOut);
ventoy_clear_input(); ventoy_clear_input();
ventoy_parse_cmdline(ImageHandle); Status = ventoy_parse_cmdline(ImageHandle);
if (EFI_ERROR(Status))
{
return Status;
}
if (gMemdiskMode) if (gMemdiskMode)
{ {
@@ -1000,22 +1073,24 @@ EFI_STATUS EFIAPI VentoyEfiMain
else else
{ {
ventoy_save_variable(); ventoy_save_variable();
ventoy_find_iso_disk(ImageHandle); Status = ventoy_find_iso_disk(ImageHandle);
if (!EFI_ERROR(Status))
if (gLoadIsoEfi)
{ {
ventoy_find_iso_disk_fs(ImageHandle); if (gLoadIsoEfi)
ventoy_load_isoefi_driver(ImageHandle); {
ventoy_find_iso_disk_fs(ImageHandle);
ventoy_load_isoefi_driver(ImageHandle);
}
ventoy_debug_pause();
ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes);
ventoy_debug_pause();
Status = ventoy_boot(ImageHandle);
} }
ventoy_debug_pause();
ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes);
ventoy_debug_pause();
Status = ventoy_boot(ImageHandle);
ventoy_clean_env(); ventoy_clean_env();
} }

View File

@@ -185,6 +185,9 @@ typedef struct ventoy_virt_chunk
#error Unknown Processor Type #error Unknown Processor Type
#endif #endif
#define VENTOY_DEVICE_WARN 1
#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!"
typedef struct ventoy_sector_flag typedef struct ventoy_sector_flag
{ {
UINT8 flag; // 0:init 1:mem 2:remap UINT8 flag; // 0:init 1:mem 2:remap
@@ -275,6 +278,32 @@ typedef struct ventoy_iso9660_override
UINT32 size_be; UINT32 size_be;
}ventoy_iso9660_override; }ventoy_iso9660_override;
typedef struct PART_TABLE
{
UINT8 Active; // 0x00 0x80
UINT8 StartHead;
UINT16 StartSector : 6;
UINT16 StartCylinder : 10;
UINT8 FsFlag;
UINT8 EndHead;
UINT16 EndSector : 6;
UINT16 EndCylinder : 10;
UINT32 StartSectorId;
UINT32 SectorCount;
}PART_TABLE;
typedef struct MBR_HEAD
{
UINT8 BootCode[446];
PART_TABLE PartTbl[4];
UINT8 Byte55;
UINT8 ByteAA;
}MBR_HEAD;
#pragma pack() #pragma pack()

View File

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

View File

@@ -1591,6 +1591,7 @@ module = {
common = ventoy/ventoy_linux.c; common = ventoy/ventoy_linux.c;
common = ventoy/ventoy_unix.c; common = ventoy/ventoy_unix.c;
common = ventoy/ventoy_windows.c; common = ventoy/ventoy_windows.c;
common = ventoy/ventoy_vhd.c;
common = ventoy/ventoy_plugin.c; common = ventoy/ventoy_plugin.c;
common = ventoy/ventoy_json.c; common = ventoy/ventoy_json.c;
common = ventoy/lzx.c; common = ventoy/lzx.c;

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

View 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

View File

@@ -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)
@@ -999,6 +1008,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
grub_menu_execute_entry (e, 0); grub_menu_execute_entry (e, 0);
if (autobooted) if (autobooted)
break; break;
if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_RET", 12) == 0)
break;
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;

View File

@@ -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"),

File diff suppressed because it is too large Load Diff

View File

@@ -28,7 +28,9 @@
#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 JSON_SUCCESS 0 #define JSON_SUCCESS 0
#define JSON_FAILED 1 #define JSON_FAILED 1
@@ -48,6 +50,14 @@
#define ventoy_get_env(key) ventoy_env_op1(get, key) #define ventoy_get_env(key) ventoy_env_op1(get, key)
#define ventoy_set_env(key, val) ventoy_env_op2(set, key, val) #define ventoy_set_env(key, val) ventoy_env_op2(set, key, val)
#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;
@@ -99,6 +109,18 @@ typedef int (*grub_char_check_func)(int c);
#define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit) #define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit)
#pragma pack(1)
typedef struct ventoy_patch_vhd
{
grub_uint8_t part_offset_or_guid[16];
grub_uint32_t reserved1;
grub_uint32_t part_type;
grub_uint8_t disk_signature_or_guid[16];
grub_uint8_t reserved2[16];
grub_uint8_t vhd_file_path[1];
}ventoy_patch_vhd;
#pragma pack()
// El Torito Boot Record Volume Descriptor // El Torito Boot Record Volume Descriptor
#pragma pack(1) #pragma pack(1)
typedef struct eltorito_descriptor typedef struct eltorito_descriptor
@@ -137,10 +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_vtoy 5
typedef struct img_info typedef struct img_info
{ {
@@ -154,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;
@@ -174,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;
@@ -604,8 +631,88 @@ typedef struct ventoy_mbr_head
grub_uint8_t Byte55; grub_uint8_t Byte55;
grub_uint8_t ByteAA; grub_uint8_t ByteAA;
}ventoy_mbr_head; }ventoy_mbr_head;
typedef struct ventoy_gpt_head
{
char Signature[8]; /* EFI PART */
grub_uint8_t Version[4];
grub_uint32_t Length;
grub_uint32_t Crc;
grub_uint8_t Reserved1[4];
grub_uint64_t EfiStartLBA;
grub_uint64_t EfiBackupLBA;
grub_uint64_t PartAreaStartLBA;
grub_uint64_t PartAreaEndLBA;
grub_uint8_t DiskGuid[16];
grub_uint64_t PartTblStartLBA;
grub_uint32_t PartTblTotNum;
grub_uint32_t PartTblEntryLen;
grub_uint32_t PartTblCrc;
grub_uint8_t Reserved2[420];
}ventoy_gpt_head;
typedef struct ventoy_gpt_part_tbl
{
grub_uint8_t PartType[16];
grub_uint8_t PartGuid[16];
grub_uint64_t StartLBA;
grub_uint64_t LastLBA;
grub_uint64_t Attr;
grub_uint16_t Name[36];
}ventoy_gpt_part_tbl;
typedef struct ventoy_gpt_info
{
ventoy_mbr_head MBR;
ventoy_gpt_head Head;
ventoy_gpt_part_tbl PartTbl[128];
}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
{
grub_uint32_t width;
grub_uint32_t height;
grub_uint32_t bpp;
}ventoy_video_mode;
typedef struct file_fullpath typedef struct file_fullpath
{ {
char path[256]; char path[256];
@@ -663,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;
@@ -672,6 +790,22 @@ typedef struct injection_config
struct injection_config *next; struct injection_config *next;
}injection_config; }injection_config;
typedef struct auto_memdisk
{
int pathlen;
char isopath[256];
struct auto_memdisk *next;
}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;
@@ -680,7 +814,14 @@ extern int g_ventoy_iso_raw;
extern int g_ventoy_iso_uefi_drv; extern int g_ventoy_iso_uefi_drv;
extern int g_ventoy_case_insensitive; extern int g_ventoy_case_insensitive;
extern grub_uint8_t g_ventoy_chain_type; extern grub_uint8_t g_ventoy_chain_type;
extern int g_vhdboot_enable;
extern int g_plugin_image_list;
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) \
{ \ { \
@@ -711,6 +852,9 @@ int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, vento
const char * ventoy_plugin_get_injection(const char *isopath); const char * ventoy_plugin_get_injection(const char *isopath);
const char * ventoy_plugin_get_menu_alias(int type, const char *isopath); const char * ventoy_plugin_get_menu_alias(int type, const char *isopath);
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_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);
@@ -720,12 +864,19 @@ 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);
grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args);
int ventoy_check_device_result(int ret);
int ventoy_check_device(grub_device_t dev);
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_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__ */

View File

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

View File

@@ -45,6 +45,9 @@ static persistence_config *g_persistence_head = NULL;
static menu_alias *g_menu_alias_head = NULL; 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 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)
{ {
@@ -67,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
{ {
@@ -1010,6 +1021,306 @@ 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)
{
VTOY_JSON *pNode = NULL;
auto_memdisk *node = NULL;
auto_memdisk *next = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY)
{
debug("Not array %d\n", json->enDataType);
return 0;
}
if (g_auto_memdisk_head)
{
for (node = g_auto_memdisk_head; node; node = next)
{
next = node->next;
grub_free(node);
}
g_auto_memdisk_head = NULL;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType == JSON_TYPE_STRING)
{
node = grub_zalloc(sizeof(auto_memdisk));
if (node)
{
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal);
if (g_auto_memdisk_head)
{
node->next = g_auto_memdisk_head;
}
g_auto_memdisk_head = node;
}
}
}
return 0;
}
static int ventoy_plugin_auto_memdisk_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 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 },
@@ -1019,11 +1330,15 @@ static plugin_entry g_plugin_entries[] =
{ "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check }, { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
{ "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 },
{ "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);
@@ -1032,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);
@@ -1063,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)
{ {
@@ -1086,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;
@@ -1163,9 +1482,15 @@ void ventoy_plugin_dump_persistence(void)
install_template * ventoy_plugin_find_install_template(const char *isopath) install_template * ventoy_plugin_find_install_template(const char *isopath)
{ {
int len;
install_template *node = NULL; install_template *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_install_template_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_install_template_head; node; node = node->next) for (node = g_install_template_head; node; node = node->next)
{ {
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
@@ -1197,9 +1522,15 @@ char * ventoy_plugin_get_cur_install_template(const char *isopath)
persistence_config * ventoy_plugin_find_persistent(const char *isopath) persistence_config * ventoy_plugin_find_persistent(const char *isopath)
{ {
int len;
persistence_config *node = NULL; persistence_config *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_persistence_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_persistence_head; node; node = node->next) for (node = g_persistence_head; node; node = node->next)
{ {
if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0)) if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0))
@@ -1272,9 +1603,15 @@ end:
const char * ventoy_plugin_get_injection(const char *isopath) const char * ventoy_plugin_get_injection(const char *isopath)
{ {
int len;
injection_config *node = NULL; injection_config *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_injection_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_injection_head; node; node = node->next) for (node = g_injection_head; node; node = node->next)
{ {
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
@@ -1288,9 +1625,15 @@ 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)
{ {
int len;
menu_alias *node = NULL; menu_alias *node = NULL;
int len = (int)grub_strlen(isopath);
if (!g_menu_alias_head)
{
return NULL;
}
len = (int)grub_strlen(isopath);
for (node = g_menu_alias_head; node; node = node->next) for (node = g_menu_alias_head; node; node = node->next)
{ {
if (node->type == type && node->pathlen && if (node->type == type && node->pathlen &&
@@ -1305,9 +1648,16 @@ 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 len;
menu_class *node = NULL; menu_class *node = NULL;
int len = (int)grub_strlen(name);
if (!g_menu_class_head)
{
return NULL;
}
len = (int)grub_strlen(name);
if (vtoy_class_image_file == type) if (vtoy_class_image_file == type)
{ {
for (node = g_menu_class_head; node; node = node->next) for (node = g_menu_class_head; node; node = node->next)
@@ -1332,11 +1682,91 @@ const char * ventoy_plugin_get_menu_class(int type, const char *name)
return NULL; return NULL;
} }
int ventoy_plugin_check_memdisk(const char *isopath)
{
int len;
auto_memdisk *node = NULL;
if (!g_auto_memdisk_head)
{
return 0;
}
len = (int)grub_strlen(isopath);
for (node = g_auto_memdisk_head; node; node = node->next)
{
if (node->pathlen == len && grub_strncmp(isopath, node->isopath, len) == 0)
{
return 1;
}
}
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;
@@ -1379,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;
} }

View File

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

View File

@@ -0,0 +1,559 @@
/******************************************************************************
* ventoy_vhd.c
*
* 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/>.
*
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/device.h>
#include <grub/term.h>
#include <grub/partition.h>
#include <grub/file.h>
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/datetime.h>
#include <grub/i18n.h>
#include <grub/net.h>
#include <grub/time.h>
#include <grub/crypto.h>
#include <grub/charset.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#endif
#include <grub/ventoy.h>
#include "ventoy_def.h"
GRUB_MOD_LICENSE ("GPLv3+");
static int g_vhdboot_bcd_offset = 0;
static int g_vhdboot_bcd_len = 0;
static int g_vhdboot_isolen = 0;
static char *g_vhdboot_totbuf = 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)
{
grub_uint32_t offset;
grub_file_t file;
char cmdbuf[128];
grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback vhdiso mem:0x%lx:size:%d", (ulong)g_vhdboot_isobuf, g_vhdboot_isolen);
grub_script_execute_sourcecode(cmdbuf);
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(vhdiso)/boot/bcd");
if (!file)
{
grub_printf("Failed to open bcd file in the image file\n");
return 1;
}
grub_file_read(file, &offset, 4);
offset = (grub_uint32_t)grub_iso9660_get_last_read_pos(file);
*bcdoffset = (int)offset;
*bcdlen = (int)file->size;
debug("vhdiso bcd file offset:%d len:%d\n", *bcdoffset, *bcdlen);
grub_file_close(file);
grub_script_execute_sourcecode("loopback -d vhdiso");
return 0;
}
static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2)
{
int i;
int cnt = 0;
char *pos;
grub_size_t pathlen;
const char *plat;
grub_uint16_t *unicode_path;
const grub_uint8_t winloadexe[] =
{
0x77, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2E, 0x00,
0x65, 0x00, 0x78, 0x00, 0x65, 0x00
};
pathlen = sizeof(grub_uint16_t) * (grub_strlen(vhdpath) + 1);
debug("unicode path for <%s> len:%d\n", vhdpath, (int)pathlen);
unicode_path = grub_zalloc(pathlen);
if (!unicode_path)
{
return 0;
}
plat = grub_env_get("grub_platform");
if (plat && (plat[0] == 'e')) /* UEFI */
{
pos = g_vhdboot_isobuf + g_vhdboot_bcd_offset;
/* winload.exe ==> winload.efi */
for (i = 0; i + (int)sizeof(winloadexe) < g_vhdboot_bcd_len; i++)
{
if (*((grub_uint32_t *)(pos + i)) == 0x00690077 &&
grub_memcmp(pos + i, winloadexe, sizeof(winloadexe)) == 0)
{
pos[i + sizeof(winloadexe) - 4] = 0x66;
pos[i + sizeof(winloadexe) - 2] = 0x69;
cnt++;
}
}
debug("winload patch %d times\n", cnt);
}
for (pos = vhdpath; *pos; pos++)
{
if (*pos == '/')
{
*pos = '\\';
}
}
grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)vhdpath, -1, NULL);
grub_memcpy(patch1->vhd_file_path, unicode_path, pathlen);
grub_memcpy(patch2->vhd_file_path, unicode_path, pathlen);
return 0;
}
static int ventoy_vhd_patch_disk(ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2)
{
char efipart[16] = {0};
grub_memcpy(efipart, g_ventoy_part_info->Head.Signature, sizeof(g_ventoy_part_info->Head.Signature));
debug("part1 type: 0x%x <%s>\n", g_ventoy_part_info->MBR.PartTbl[0].FsFlag, efipart);
if (grub_strncmp(efipart, "EFI PART", 8) == 0)
{
ventoy_debug_dump_guid("GPT disk GUID: ", g_ventoy_part_info->Head.DiskGuid);
ventoy_debug_dump_guid("GPT part GUID: ", g_ventoy_part_info->PartTbl[0].PartGuid);
grub_memcpy(patch1->disk_signature_or_guid, g_ventoy_part_info->Head.DiskGuid, 16);
grub_memcpy(patch1->part_offset_or_guid, g_ventoy_part_info->PartTbl[0].PartGuid, 16);
grub_memcpy(patch2->disk_signature_or_guid, g_ventoy_part_info->Head.DiskGuid, 16);
grub_memcpy(patch2->part_offset_or_guid, g_ventoy_part_info->PartTbl[0].PartGuid, 16);
patch1->part_type = patch2->part_type = 0;
}
else
{
debug("MBR disk signature: %02x%02x%02x%02x\n",
g_ventoy_part_info->MBR.BootCode[0x1b8 + 0], g_ventoy_part_info->MBR.BootCode[0x1b8 + 1],
g_ventoy_part_info->MBR.BootCode[0x1b8 + 2], g_ventoy_part_info->MBR.BootCode[0x1b8 + 3]);
grub_memcpy(patch1->disk_signature_or_guid, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4);
grub_memcpy(patch2->disk_signature_or_guid, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4);
}
return 0;
}
grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args)
{
int rc;
ventoy_patch_vhd *patch1;
ventoy_patch_vhd *patch2;
char envbuf[64];
(void)ctxt;
(void)argc;
grub_env_unset("vtoy_vhd_buf_addr");
debug("patch vhd <%s>\n", args[0]);
if ((!g_vhdboot_enable) || (!g_vhdboot_totbuf))
{
debug("vhd boot not ready %d %p\n", g_vhdboot_enable, g_vhdboot_totbuf);
return 0;
}
rc = ventoy_vhd_find_bcd(&g_vhdboot_bcd_offset, &g_vhdboot_bcd_len);
if (rc)
{
debug("failed to get bcd location %d\n", rc);
return 0;
}
patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x495a);
patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x50aa);
ventoy_vhd_patch_disk(patch1, patch2);
ventoy_vhd_patch_path(args[0], patch1, patch2);
/* set buffer and size */
#ifdef GRUB_MACHINE_EFI
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_totbuf);
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", (int)(g_vhdboot_isolen + sizeof(ventoy_chain_head)));
grub_env_set("vtoy_vhd_buf_size", envbuf);
#else
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_isobuf);
grub_env_set("vtoy_vhd_buf_addr", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%d", g_vhdboot_isolen);
grub_env_set("vtoy_vhd_buf_size", envbuf);
#endif
return 0;
}
grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args)
{
int buflen;
grub_file_t file;
(void)ctxt;
(void)argc;
g_vhdboot_enable = 0;
grub_check_free(g_vhdboot_totbuf);
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (!file)
{
return 0;
}
debug("load vhd boot: <%s> <%lu>\n", args[0], (ulong)file->size);
if (file->size < VTOY_SIZE_1KB * 32)
{
grub_file_close(file);
return 0;
}
g_vhdboot_isolen = (int)file->size;
buflen = (int)(file->size + sizeof(ventoy_chain_head));
#ifdef GRUB_MACHINE_EFI
g_vhdboot_totbuf = (char *)grub_efi_allocate_iso_buf(buflen);
#else
g_vhdboot_totbuf = (char *)grub_malloc(buflen);
#endif
if (!g_vhdboot_totbuf)
{
grub_file_close(file);
return 0;
}
g_vhdboot_isobuf = g_vhdboot_totbuf + sizeof(ventoy_chain_head);
grub_file_read(file, g_vhdboot_isobuf, file->size);
grub_file_close(file);
g_vhdboot_enable = 1;
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);
}

View File

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

View File

@@ -12,17 +12,23 @@ 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 "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos'
#grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/bootx64.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos'
else else
all_modules="$net_modules_legacy $all_modules_legacy " all_modules="$net_modules_legacy $all_modules_legacy "
grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk'
#grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/cdrom.img" --format 'i386-pc-eltorito' --compression 'auto' $all_modules_legacy 'biosdisk' 'iso9660' 'fat' 'part_msdos'
#rm -f $VT_DIR/LiveCD/GRUB/boot_hybrid.img
#cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot_hybrid.img $VT_DIR/LiveCD/GRUB/boot_hybrid.img
fi fi
grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1 grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1

View File

@@ -35,14 +35,32 @@ fi
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" 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 if [ -n "$1" ]; then
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 "ln -s /dev/$vtDM $1" vtlog "ln -s /dev/$vtDM $1"
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 fi
# OK finish # OK finish
set_ventoy_hook_finish set_ventoy_hook_finish

View File

@@ -24,9 +24,12 @@ if $GREP -q '^"$mount_handler"' /init; then
vthookfile=/hooks/archiso vthookfile=/hooks/archiso
if [ -e /hook/miso ]; then if [ -e /hooks/miso ]; then
vthookfile=/hooks/miso vthookfile=/hooks/miso
$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$misodevice\"" -i /init $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$misodevice\"" -i /init
elif [ -e /hooks/artix ]; then
vthookfile=/hooks/artix
$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$artixdevice\"" -i /init
else else
$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init
fi fi

View File

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

View 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 $*

View File

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

View File

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

View File

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

View File

@@ -78,10 +78,10 @@ DISTRO=$(ventoy_get_debian_distro)
echo "##### distribution = $DISTRO ######" >> $VTLOG echo "##### distribution = $DISTRO ######" >> $VTLOG
. $VTOY_PATH/hook/debian/${DISTRO}-hook.sh . $VTOY_PATH/hook/debian/${DISTRO}-hook.sh
if [ -f /bin/env2debconf ]; then
$SED "1a /bin/sh $VTOY_PATH/hook/debian/ventoy_env2debconf.sh" -i /bin/env2debconf
$SED "s#in *\$(set)#in \$(cat /ventoy/envset)#" -i /bin/env2debconf
fi

View File

@@ -0,0 +1,33 @@
#!/bin/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/>.
#
#************************************************************************************
PATH=$PATH:/ventoy/busybox
set > /ventoy/tmpenvset
for i in $(cat /proc/cmdline); do
if echo $i | grep -q "="; then
vtKey=${i%=*}
if ! grep -q "^$vtKey" /ventoy/tmpenvset; then
echo $i >> /ventoy/envset
fi
fi
done
cat /ventoy/tmpenvset >> /ventoy/envset

View File

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

View 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

View File

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

View File

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

View File

@@ -349,7 +349,7 @@ fi
cd / cd /
unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD vtcmdline
for vtinit in $user_rdinit /init /sbin/init /linuxrc; do for vtinit in $user_rdinit /init /sbin/init /linuxrc; do
if [ -d /ventoy_rdroot ]; then if [ -d /ventoy_rdroot ]; then

View File

@@ -23,6 +23,9 @@ while [ -n "$1" ]; do
elif [ "$1" = "-l" ]; then elif [ "$1" = "-l" ]; then
shift shift
label=$1 label=$1
elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
print_usage
exit 0
else else
print_usage print_usage
exit 1 exit 1

Binary file not shown.

Binary file not shown.

View File

@@ -1,21 +1,26 @@
#!/bin/sh #!/bin/sh
if ! [ -f ./tool/ventoy_lib.sh ]; then
echo '' if [ -f ${0%Ventoy2Disk.sh}/tool/ventoy_lib.sh ]; then
echo '***********************************************************'
echo '* Ventoy2Disk Script *'
echo '* longpanda admin@ventoy.net *'
echo '***********************************************************'
echo ''
OLDDIR=$PWD
if ! [ -f ./tool/xzcat ]; then
if [ -f ${0%Ventoy2Disk.sh}/tool/xzcat ]; then
cd ${0%Ventoy2Disk.sh} cd ${0%Ventoy2Disk.sh}
fi fi
fi fi
if [ -f ./ventoy/version ]; then
curver=$(cat ./ventoy/version)
fi
echo ''
echo '**********************************************'
echo " Ventoy: $curver"
echo " longpanda admin@ventoy.net"
echo " https://www.ventoy.net"
echo '**********************************************'
echo ''
OLDDIR=$(pwd)
PATH=./tool:$PATH
if ! [ -f ./boot/boot.img ]; then if ! [ -f ./boot/boot.img ]; then
if [ -d ./grub ]; then if [ -d ./grub ]; then
echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it." echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it."
@@ -26,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

View File

@@ -1,3 +1,5 @@
submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json {
menuentry 'Check global control plugin configuration' --class=debug_control { menuentry 'Check global control plugin configuration' --class=debug_control {
set pager=1 set pager=1
@@ -63,7 +65,34 @@ 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 auto memdisk plugin configuration' --class=debug_automemdisk {
set pager=1
vt_check_plugin_json $vt_plugin_path auto_memdisk $vtoy_iso_part
echo -e "\npress ENTER to exit ..."
read vtInputKey
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 ...'
@@ -71,6 +100,43 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json {
} }
submenu "Resolution Configuration" --class=debug_resolution {
menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
echo 'Return ...'
}
vt_update_cur_video_mode VT_CUR_MODE
set vdid=0
while [ $vdid -lt $VTOY_VIDEO_MODE_NUM ]; do
vt_get_video_mode $vdid vtCurMode
unset vtActive
if [ "$vtCurMode" = "$VT_CUR_MODE" ]; then
set vtActive="[*]"
fi
menuentry "$vtCurMode $vtActive" --class=debug_videomode VTOY_RUN_RET {
terminal_output console
set gfxmode=$1
terminal_output gfxterm
}
vt_incr vdid 1
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 {
menuentry 'Fixup Windows BlinitializeLibrary Failure' { menuentry 'Fixup Windows BlinitializeLibrary Failure' {

View File

@@ -44,15 +44,22 @@ 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
} }
function ventoy_diagnosis { function ventoy_diagnosis {
vt_enum_video_mode
configfile $prefix/debug.cfg configfile $prefix/debug.cfg
} }
function ventoy_localboot { function ventoy_localboot {
configfile $prefix/localboot.cfg configfile $prefix/localboot.cfg
} }
@@ -251,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
} }
@@ -429,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
@@ -439,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
@@ -471,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
@@ -489,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
@@ -505,6 +539,10 @@ function uefi_linux_menu_func {
elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then
vt_add_replace_file 0 "EFI\\hyperiso\\hyperiso.img" vt_add_replace_file 0 "EFI\\hyperiso\\hyperiso.img"
fi fi
elif [ -d (loop)/EFI/BOOT/entries ]; then
if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then
vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img"
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"
set FirstTryBootFile='@EFI@BOOT@grubx64.efi' set FirstTryBootFile='@EFI@BOOT@grubx64.efi'
@@ -517,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
@@ -530,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
@@ -582,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}
@@ -641,7 +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
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
boot boot
else else
echo "chain empty failed" echo "chain empty failed"
@@ -705,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
@@ -718,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
@@ -747,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
@@ -759,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}
@@ -813,7 +864,7 @@ function ventoy_iso_busybox_ver {
#special process for deepin-live iso #special process for deepin-live iso
if [ "$vt_chosen_size" = "403701760" ]; then if [ "$vt_chosen_size" = "403701760" ]; then
if vt_str_begin $vt_chosen_path "/deepin-live"; then if vt_str_str $vt_chosen_path "/deepin-live"; then
set ventoy_busybox_ver=64 set ventoy_busybox_ver=64
fi fi
elif vt_str_begin $vt_volume_id "PHOTON_"; then elif vt_str_begin $vt_volume_id "PHOTON_"; then
@@ -855,6 +906,21 @@ function iso_common_menuentry {
fi fi
} }
function miso_common_menuentry {
vt_chosen_img_path vt_chosen_path vt_chosen_size
echo "memdisk mode boot for $vt_chosen_path"
echo ""
ventoy_debug_pause
if [ "$grub_platform" = "pc" ]; then
legacy_iso_memdisk $vtoy_iso_part $vt_chosen_path
else
uefi_iso_memdisk $vtoy_iso_part $vt_chosen_path
fi
}
function common_unsupport_menuentry { function common_unsupport_menuentry {
echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n" echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n"
echo -e " 文件名中不能有中文或空格 \n" echo -e " 文件名中不能有中文或空格 \n"
@@ -862,6 +928,10 @@ function common_unsupport_menuentry {
read vtInputKey read vtInputKey
} }
function miso_unsupport_menuentry {
common_unsupport_menuentry
}
function iso_unsupport_menuentry { function iso_unsupport_menuentry {
common_unsupport_menuentry common_unsupport_menuentry
} }
@@ -874,7 +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}
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}
@@ -917,6 +987,109 @@ function efi_unsupport_menuentry {
common_unsupport_menuentry common_unsupport_menuentry
} }
function vhd_common_menuentry {
if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then
if [ "$vtoy_iso_fs" != "ntfs" ]; then
echo -e "!!! WARNING !!!\n"
echo -e "\nPartition1 ($vtoy_iso_fs) is NOT ntfs, the VHD(x) file may not boot normally \n"
echo -e "\nVHD(x) 文件所在分区不是 ntfs 格式, 可能无法正常启动 \n\n"
echo -n "press ENTER to continue boot (请按 回车 键继续) ..."
read vtInputKey
fi
fi
vt_chosen_img_path vt_chosen_path vt_chosen_size
vt_patch_vhdboot $vt_chosen_path
ventoy_debug_pause
if [ -n "$vtoy_vhd_buf_addr" ]; then
if [ "$grub_platform" = "pc" ]; then
linux16 $vtoy_path/memdisk iso raw
initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
boot
else
ventoy_cli_console
chainloader ${vtoy_path}/ventoy_x64.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size}
boot
ventoy_gui_console
fi
else
echo "Please put the right ventoy_vhdboot.img file to the 1st partition"
ventoy_pause
fi
}
function vhd_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 #
@@ -1158,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
@@ -1185,7 +1360,10 @@ function img_unsupport_menuentry {
############################################################# #############################################################
############################################################# #############################################################
set VENTOY_VERSION="1.0.20" 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
@@ -1212,16 +1390,17 @@ vt_device $root vtoy_dev
if [ "$vtoy_dev" = "tftp" ]; then if [ "$vtoy_dev" = "tftp" ]; then
set vtoy_path=($root) set vtoy_path=($root)
for vtid in 0 1 2 3; do for vtid in 0 1 2 3; do
if [ -d (hd$vtid,2)/ventoy ]; then if [ -f (hd$vtid,2)/ventoy/ventoy.cpio ]; then
set vtoy_iso_part=(hd$vtid,1) set vtoy_iso_part=(hd$vtid,1)
set vtoy_efi_part=(hd$vtid,2) set vtoy_efi_part=(hd$vtid,2)
set vtoydev=hd$vtid
break break
fi fi
done done
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
@@ -1233,12 +1412,15 @@ else
set vtoy_path=($root)/ventoy set vtoy_path=($root)/ventoy
fi fi
set vtoydev=$vtoy_dev
set vtoy_iso_part=($vtoy_dev,1) set vtoy_iso_part=($vtoy_dev,1)
set vtoy_efi_part=($vtoy_dev,2) set vtoy_efi_part=($vtoy_dev,2)
loadfont unicode loadfont unicode
set vt_plugin_path=$vtoy_iso_part set vt_plugin_path=$vtoy_iso_part
fi fi
#Load Partition Table
vt_load_part_table $vtoydev
#Load Plugin #Load Plugin
if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then
@@ -1257,22 +1439,31 @@ elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then
vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img
fi fi
if [ -f $vtoy_iso_part/ventoy/ventoy_vhdboot.img ]; then
vt_load_vhdboot $vtoy_iso_part/ventoy/ventoy_vhdboot.img
elif [ -f $vtoy_efi_part/ventoy/ventoy_vhdboot.img ]; then
vt_load_vhdboot $vtoy_efi_part/ventoy/ventoy_vhdboot.img
fi
if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then
set VTOY_F3_CMD="vt_dynamic_menu 1 1" set VTOY_F3_CMD="vt_dynamic_menu 1 1"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Debug F6:ExMenu" set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Tools F6:ExMenu"
else else
set VTOY_F3_CMD="vt_dynamic_menu 1 0" set VTOY_F3_CMD="vt_dynamic_menu 1 0"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Debug F6:ExMenu" set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Tools F6:ExMenu"
fi fi
if [ -n "$vtoy_gfxmode" ]; then if [ -n "$vtoy_gfxmode" ]; then
set gfxmode=$vtoy_gfxmode set gfxmode=$vtoy_gfxmode
set gfxpayload=keep
else else
set gfxmode=1920x1080,1366x768,1024x768 set gfxmode=1024x768
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
@@ -1296,16 +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 vtoy_dev export gfxpayload
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
#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.

View File

@@ -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 relocator gcry_sha1 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

View File

@@ -1,10 +1,38 @@
if [ "$grub_platform" = "pc" ]; then if [ "$grub_platform" = "pc" ]; then
menuentry 'Search and boot Windows' --class=boot_windows { menuentry 'Search and boot Windows' --class=boot_windows {
if search -n -s -f /bootmgr; then
ntldr /bootmgr set partid=3
elif search -n -s -f /NTLDR; then while [ $partid -le 128 ]; do
ntldr /NTLDR if vt_check_part_exist $partid; then
for bt in bootmgr BOOTMGR Bootmgr BootMGR; do
if [ -f ($vtoydev,$partid)/$bt ]; then
set root=($vtoydev,$partid)
ntldr /$bt
boot
fi
done
else
break
fi
vt_incr partid 1
done
if search -n -s -f /Boot/BCD; then
for bt in bootmgr BOOTMGR Bootmgr BootMGR; do
if [ -f /$bt ]; then
if regexp '^hd0' $root; then
ntldr /$bt
else
drivemap -s hd0 $root
ntldr /$bt
fi
break
fi
done
elif search -n -s -f /NTDETECT.COM; then
drivemap -s hd0 $root
ntldr /ntldr
else else
echo "Windows NOT found ..." echo "Windows NOT found ..."
fi fi
@@ -39,6 +67,22 @@ if [ "$grub_platform" = "pc" ]; then
else else
menuentry 'Search and boot Windows' --class=boot_windows { menuentry 'Search and boot Windows' --class=boot_windows {
set partid=3
while [ $partid -le 128 ]; do
if vt_check_part_exist $partid; then
if [ -f ($vtoydev,$partid)/EFI/Microsoft/Boot/bootmgfw.efi ]; then
set root=($vtoydev,$partid)
terminal_output console
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
boot
fi
else
break
fi
vt_incr partid 1
done
if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then
terminal_output console terminal_output console
chainloader /EFI/Microsoft/Boot/bootmgfw.efi chainloader /EFI/Microsoft/Boot/bootmgfw.efi

View File

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

View File

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

View File

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

View File

@@ -127,6 +127,12 @@ zip -r ventoy-${curver}-windows.zip $tmpdir/
rm -rf $tmpdir rm -rf $tmpdir
cd ../LiveCD
sh livecd.sh
cd $CurDir
mv ../LiveCD/ventoy*.iso ./
if [ -e ventoy-${curver}-windows.zip ] && [ -e ventoy-${curver}-linux.tar.gz ]; then if [ -e ventoy-${curver}-windows.zip ] && [ -e ventoy-${curver}-linux.tar.gz ]; then
echo -e "\n ============= SUCCESS =================\n" echo -e "\n ============= SUCCESS =================\n"
else else

View File

@@ -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, &param->guid, sizeof(ventoy_guid)); memcpy(&location->guid, &param->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)

View File

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

View File

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

View File

@@ -0,0 +1,4 @@
tinycore follows the GPL-v2 License (see gpl-2.0.txt)
Ventoy does not modify its source code, only its binraries are used.

BIN
LiveCD/GRUB/boot_hybrid.img Normal file

Binary file not shown.

BIN
LiveCD/GRUB/bootx64.efi Normal file

Binary file not shown.

BIN
LiveCD/GRUB/cdrom.img Normal file

Binary file not shown.

5
LiveCD/GRUB/embed.cfg Normal file
View File

@@ -0,0 +1,5 @@
search -f /EFI/VentoyLiveCD -s root
configfile ($root)/EFI/boot/grub.cfg

View File

@@ -0,0 +1,3 @@
VentoyLiveCD
https://www.ventoy.net

View File

@@ -0,0 +1,17 @@
set timeout=3
set default=LiveCD
clear
menuentry 'Ventoy xxx LiveCD' --id=LiveCD {
linux /EFI/boot/vmlinuz quiet loglevel=0 superuser rdinit=/ventoy/init.sh
initrd /EFI/ventoy/ventoy.gz /EFI/boot/core.gz /EFI/boot/modules.gz newc:ventoy.tar.gz:/EFI/ventoy/ventoy-xxx-linux.tar.gz
boot
}
menuentry 'Ventoy xxx LiveCD (Debug Mode)' {
linux /EFI/boot/vmlinuz loglevel=10 multivt superuser rdinit=/ventoy/init.sh
initrd /EFI/ventoy/ventoy.gz /EFI/boot/core.gz /EFI/boot/modules.gz newc:ventoy.tar.gz:/EFI/ventoy/ventoy-xxx-linux.tar.gz
boot
}

34
LiveCD/README.txt Normal file
View File

@@ -0,0 +1,34 @@
Ventoy LiveCD is Tinycore distro + Ventoy linux install package.
vmlinuz and core.gz are downloaded from:
http://www.tinycorelinux.net/11.x/x86/release/distribution_files/
MD5SUM:
0fd08c73e84b26aabbd0d12006d64855 core.gz
a9c2e2abbf464517e681234fb4687aa1 vmlinuz
VTOY/ventoy/tcz/*/tcz are downloaded from:
http://distro.ibiblio.org/tinycorelinux/11.x/x86/tcz/
MD5SUM:
b6153a469d1d56e1e6895c6812a344cd dosfstools.tcz
29a4585d38b34ad58f8a7cb2d09e065f glib2.tcz
6812067a60165aee3cbcc07a75b6b1f4 libffi.tcz
5120e0c9ee65f936dea8cb6a0a0a1ddd liblvm2.tcz
92909db8fb3c4333a2a4a325ffbf4b50 ncursesw.tcz
e2bb47c9da2abab62fa794d69aba97c0 parted.tcz
0e6dfbebe816062a81aff6d3e5e7719b readline.tcz
3cf996373ab01be269ea0efaf17ce0cd udev-lib.tcz
VTOY/ventoy/drivers/*.ko
build kernel
http://www.tinycorelinux.net/11.x/x86/release/src/kernel/
config-5.4.3-tinycore
linux-5.4.3-patched.txz
disable a wireless lan driver to avoid compile error

View File

@@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned long long UINT64;
int GetHumanReadableGBSize(UINT64 SizeBytes)
{
int i;
int Pow2 = 1;
double Delta;
double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000;
for (i = 0; i < 12; i++)
{
if (Pow2 > GB)
{
Delta = (Pow2 - GB) / Pow2;
}
else
{
Delta = (GB - Pow2) / Pow2;
}
if (Delta < 0.05)
{
return Pow2;
}
Pow2 <<= 1;
}
return (int)GB;
}
int main(int argc, char **argv)
{
UINT64 value = strtoul(argv[1], NULL, 10);
printf("%d", GetHumanReadableGBSize(value * 512));
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,12 @@
#!/bin/sh
cat /ventoy/modlist | while read line; do
if [ -e /ventoy/drivers/${line}.ko ]; then
insmod /ventoy/drivers/${line}.ko
fi
done
sleep 5
echo "sh /ventoy/profile.sh" >> /root/.profile
exec /init

View File

@@ -0,0 +1,27 @@
scsi_transport_sas
mptbase
mptscsih
mptsas
yurex
ezusb
parport
uss720
usb4604
usb3503
sisusbvga
usb251xb
pi3usb30532
usb-otg-fsm
usb-conn-gpio
ulpi
ums-realtek
xhci-hcd
xhci-pci
xhci-plat-hcd
usbip-core
usbip-host
vhci-hcd
cdc-wdm
cdc-acm
usblp
megaraid_sas

View File

@@ -0,0 +1,22 @@
#!/bin/sh
cd /
tar -xf ventoy.tar.gz
cd /ventoy
mkdir mnt
for i in $(ls tcz/*.tcz); do
mount $i mnt
cp -a mnt/* /
umount mnt
done
ldconfig /usr/local/lib /usr/lib /lib
#workaround for swapon
rm -f /sbin/swapon
echo '#!/bin/sh' > /sbin/swapon
chmod +x /sbin/swapon
sh /ventoy/ventoy.sh

Binary file not shown.

View File

@@ -0,0 +1,298 @@
#!/bin/sh
info() {
echo -e "\033[32m$*\033[0m"
}
warn() {
echo -e "\033[33m$*\033[0m"
}
err() {
echo -e "\033[31m$*\033[0m"
}
get_disk_size() {
sec=$(cat /sys/block/$1/size)
/ventoy/disksize $sec
}
enum_disk() {
id=1
rm -f /device.list
ls /sys/block/ | egrep 'd[a-z]|nvme|mmc' | while read dev; do
if ! [ -b /dev/$dev ]; then
continue
fi
size=$(get_disk_size $dev)
model=$(parted -s /dev/$dev p 2>/dev/null | grep Model | sed 's/Model: \(.*\)/\1/')
printf " <%d> %-4s %3s GB %s\r\n" $id "$dev" "$size" "$model" >> /device.list
id=$(expr $id + 1)
done
}
select_disk() {
echo "" > /dev/console
echo "" > /dev/console
if [ -f /device.list ]; then
lines=$(cat /device.list | wc -l)
cat /device.list > /dev/console
else
echo -e "\033[31m !!! NO device detected !!!\033[0m" > /dev/console
lines=0
fi
echo "" > /dev/console
echo " <a> Refresh device list <b> Reboot <c> Enter shell" > /dev/console
echo "" > /dev/console
while true; do
if [ $lines -gt 0 ]; then
read -p "Please select the disk to operator [1-$lines] " Answer
else
read -p "Please choose your operation [a-c] " Answer
fi
if [ "$Answer" = "shell" ]; then
echo 8888; return
elif [ "$Answer" = "c" ] || [ "$Answer" = "C" ]; then
echo 8888; return
fi
if [ "$Answer" = "a" ] || [ "$Answer" = "A" ]; then
echo 0; return
elif [ "$Answer" = "b" ] || [ "$Answer" = "B" ]; then
read -p "Do you really want to reboot? (y/n) " Ask
if [ "$Ask" = "y" ] || [ "$Ask" = "Y" ]; then
reboot
else
continue
fi
fi
if [ -n "$Answer" ]; then
if echo $Answer | grep -q "^[1-9][0-9]*$"; then
if [ $Answer -gt 0 ] && [ $Answer -le $lines ]; then
echo $Answer
return
fi
fi
fi
done
}
get_dev_ventoy_ver() {
if ! [ -b /dev/${1}2 ]; then
echo "NO"; return
fi
mount -t vfat -o ro /dev/${1}2 /ventoy/mnt >/dev/null 2>/dev/null
if [ -e /ventoy/mnt/ventoy ] && [ -f /ventoy/mnt/grub/grub.cfg ]; then
if grep -q 'set.*VENTOY_VERSION=' /ventoy/mnt/grub/grub.cfg; then
grep 'set.*VENTOY_VERSION=' /ventoy/mnt/grub/grub.cfg | awk -F'"' '{print $2}'
else
echo 'NO'
fi
umount /ventoy/mnt
return
fi
echo "NO"
}
ventoy_configuration() {
while true; do
if [ -f /preserve.txt ]; then
SPACE=$(cat /preserve.txt)
else
SPACE=0
fi
if [ -f /secureboot.txt ]; then
SECURE=$(cat /secureboot.txt)
else
SECURE=Disable
fi
if [ -f /partstyle.txt ]; then
STYLE=$(cat /partstyle.txt)
else
STYLE=MBR
fi
echo ""
echo -e " <1> Preserve space (only for install) \033[32m[${SPACE}MB]\033[0m"
echo -e " <2> Secure boot support \033[32m[$SECURE]\033[0m"
echo -e " <3> Partition style (only for install) \033[32m[$STYLE]\033[0m"
echo " <0> Back to previous menu"
echo ""
while true; do
read -p "Please choose your operation: " Answer
if echo $Answer | grep -q "^[0-3]$"; then
break
fi
done
if [ "$Answer" = "0" ]; then
break
elif [ "$Answer" = "1" ]; then
while true; do
read -p "Please input the preserve space in MB: " Answer
if echo $Answer | grep -q "^[0-9][0-9]*$"; then
echo $Answer > /preserve.txt
break
fi
done
elif [ "$Answer" = "2" ]; then
if [ "$SECURE" = "Disable" ]; then
echo "Enable" > /secureboot.txt
else
echo "Disable" > /secureboot.txt
fi
else
if [ "$STYLE" = "GPT" ]; then
echo "MBR" > /partstyle.txt
else
echo "GPT" > /partstyle.txt
fi
fi
done
}
cd /
VTPATH=$(ls -1 | grep ventoy-)
VTVER=${VTPATH#*-}
cd $VTPATH
clear
echo ""
info "**************************************************"
vline=$(printf "* Ventoy LiveCD %6s *\r\n" "$VTVER")
info "$vline"
info "**************************************************"
echo ""
info "Scaning devices ......"
sleep 5
enum_disk
while true; do
sel=$(select_disk)
if [ $sel -eq 8888 ]; then
break
elif [ $sel -eq 0 ]; then
enum_disk
continue
fi
DEV=$(sed -n "${sel}p" /device.list | awk '{print $2}')
DevVtVer=$(get_dev_ventoy_ver $DEV)
if [ "$DevVtVer" = "NO" ]; then
while true; do
echo ""
echo " <1> Install Ventoy to $DEV"
echo " <2> Set Configuration"
echo " <0> Back to previous menu"
echo ""
while true; do
read -p "Please choose your operation: " Answer
if echo $Answer | grep -q "^[0-2]$"; then
break;
fi
done
if [ "$Answer" = "0" ]; then
break
elif [ "$Answer" = "2" ]; then
ventoy_configuration
else
opt=""
if [ -f /preserve.txt ]; then
opt="$opt -r $(cat /preserve.txt)"
fi
if [ -f /secureboot.txt ] && grep -q "Enable" /secureboot.txt; then
opt="$opt -s"
fi
if [ -f /partstyle.txt ] && grep -q "GPT" /partstyle.txt; then
opt="$opt -g"
fi
info "Ventoy2Disk.sh $opt -i /dev/$DEV"
sh Ventoy2Disk.sh $opt -i /dev/$DEV
sync
break
fi
done
else
info "Ventoy $DevVtVer detected in the device $DEV"
while true; do
echo ""
echo " <1> Update Ventoy in $DEV from $DevVtVer ==> $VTVER"
echo " <2> Re-install Ventoy to $DEV"
echo " <3> Set Configuration"
echo " <0> Back to previous menu"
echo ""
while true; do
read -p "Please choose your operation: " Answer
if echo $Answer | grep -q "^[0-3]$"; then
break;
fi
done
if [ "$Answer" = "0" ]; then
break
elif [ "$Answer" = "1" ]; then
opt=""
if [ -f /secureboot.txt ] && grep -q "Enable" /secureboot.txt; then
opt="$opt -s"
fi
info "Ventoy2Disk.sh $opt -u /dev/$DEV"
sh Ventoy2Disk.sh $opt -u /dev/$DEV
sync
break
elif [ "$Answer" = "2" ]; then
opt=""
if [ -f /preserve.txt ]; then
opt="$opt -r $(cat /preserve.txt)"
fi
if [ -f /secureboot.txt ] && grep -q "Enable" /secureboot.txt; then
opt="$opt -s"
fi
if [ -f /partstyle.txt ] && grep -q "GPT" /partstyle.txt; then
opt="$opt -g"
fi
info "Ventoy2Disk.sh $opt -I /dev/$DEV"
sh Ventoy2Disk.sh $opt -I /dev/$DEV
sync
break
else
ventoy_configuration
fi
done
fi
done

60
LiveCD/livecd.sh Normal file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
VENTOY_PATH=$PWD/../
if ! [ -f $VENTOY_PATH/INSTALL/grub/grub.cfg ]; then
echo "no grub.cfg detected"
exit 1
fi
version=$(grep 'set.*VENTOY_VERSION=' $VENTOY_PATH/INSTALL/grub/grub.cfg | awk -F'"' '{print $2}')
if ! [ -e $VENTOY_PATH/INSTALL/ventoy-${version}-linux.tar.gz ]; then
echo "no ventoy-${version}-linux.tar.gz detected"
exit 1
fi
rm -rf ISO_TMP
cp -a ISO ISO_TMP
cp -a VTOY VTOY_TMP && cd VTOY_TMP
gcc -O2 -m32 ./ventoy/disksize.c -o ./ventoy/disksize
rm -f ./ventoy/disksize.c
find . | cpio -o -H newc | gzip -9 > ../ISO_TMP/EFI/ventoy/ventoy.gz
cd .. && rm -rf VTOY_TMP
cp -a $VENTOY_PATH/INSTALL/ventoy-${version}-linux.tar.gz ISO_TMP/EFI/ventoy/
cp -a GRUB/cdrom.img ISO_TMP/EFI/boot/
cp -a GRUB/bootx64.efi ISO_TMP/EFI/boot/
rm -rf efimnt
rm -f efi.img
mkdir -p efimnt
dd if=/dev/zero of=efi.img bs=1M count=2
mkfs.vfat efi.img
mount efi.img efimnt
mkdir -p efimnt/EFI/boot
cp -a GRUB/bootx64.efi efimnt/EFI/boot/
umount efimnt
sync
cp -a efi.img ISO_TMP/EFI/boot/
rm -rf efimnt
rm -f efi.img
cd ISO_TMP
sed "s/xxx/$version/g" -i EFI/boot/grub.cfg
rm -f ../ventoy-${version}-livecd.iso
xorriso -as mkisofs -allow-lowercase --sort-weight 0 / --sort-weight 1 /EFI -v -R -J -V 'VentoyLiveCD' -P 'VENTOY COMPATIBLE' -p 'https://www.ventoy.net' -sysid 'Ventoy' -A 'VentoyLiveCD' -b EFI/boot/cdrom.img --grub2-boot-info --grub2-mbr ../GRUB/boot_hybrid.img -c EFI/boot/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e EFI/boot/efi.img -no-emul-boot -append_partition 2 0xEF EFI/boot/efi.img -o ../ventoy-${version}-livecd.iso .
cd ../
rm -rf ISO_TMP

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