Compare commits

...

21 Commits

Author SHA1 Message Date
longpanda
a5c706511b 1.0.13 release 2020-06-15 01:41:42 +08:00
Lev
785255b65f Update russian language (#218) 2020-06-14 02:03:21 +08:00
longpanda
176c819d10 file encoding 2020-06-09 23:24:05 +08:00
ensag-dev
8f2bf03084 Add Occitan language (#212)
* Add Occitan language

* Update languages.ini
2020-06-09 23:22:19 +08:00
longpanda
4408be5cf0 Update README.md 2020-06-09 12:02:49 +08:00
A1ive
74154ad9a3 Fix iPXE '-Werror=zero-length-bounds' (#202) 2020-06-06 11:31:39 +08:00
longpanda
43fcd4f262 file encoding 2020-06-04 21:43:10 +08:00
PolarniMeda
be35990666 Add Serbian language (#191)
Added Serbian translation, both latin and cyrilic.
2020-06-04 21:39:08 +08:00
François Revol
ad3db3dfcb Rename GPLv3 to LICENSE (#192)
This should allow Github to autodetect the license type and show it in the header, and also index it for project search by license.
2020-06-04 08:56:04 +08:00
PenutChen
227264f208 Add traditional Chinese (#189) 2020-06-03 23:27:53 +08:00
longpanda
1f37663285 add Hungarian (translated by Bitfarago) 2020-06-01 22:53:40 +08:00
longpanda
8cde5a4898 1.0.12 release 2020-05-30 20:13:09 +08:00
longpanda
c8e86938fe 1. Add a new feature to directly boot wim files
2. auto installation plugin update
    1) Expand the configuration, now you can specify more than one auto installation scripts for one ISO file
    2) Add a prompt for the iso with auto installation config, you can choose whether to use the auto installation script and which one to use for this time
3. persistence plugin update
    1) Expand the configuration, now you can specify more than one persistence backend image files for one ISO file
    2) Add a prompt for the iso with persistence config, you can choose whether to use the persistence image and which one to use for this time
4. Move the position of the red Memdisk tip to a more prominent position
5. Add a return parent directory item when in TreeView mode
6. Add a VTOY_DEFAULT_SEARCH_ROOT option in global control plugin to specify the root path of the iso files.
7. Change the style of F2 power menu
8. Fix a bug about Ventoy2Disk.exe can't start when there is a DataRAM Ramdisk in the system.
9. Files with size less than 32KB will be filted by default
10. Fix a bug about wrong file size in TreeView mode with NTFS/XFS
11. Files with space or Non Ascii charactors in name will be shown but with unsupported message when you boot it.
12. Optimization for Ventoy2Disk.sh
13. Optimization for arch linux boot
14. New iso support
2020-05-29 22:57:46 +08:00
Ali Mahdavi
7a0b2d945e Persian language added (#170) 2020-05-29 22:27:06 +08:00
longpanda
5089fda07d Create FUNDING.yml 2020-05-25 15:10:14 +08:00
longpanda
f77ba141fd Update README.md 2020-05-25 12:45:09 +08:00
longpanda
6d1ace0570 dos2unix 2020-05-24 20:45:04 +08:00
longpanda
a2d732c170 update ventoy_pack.sh 2020-05-24 20:43:41 +08:00
longpanda
a54b6f692c Update ventoy_lib.sh 2020-05-24 20:25:47 +08:00
longpanda
73c196a823 Update Ventoy2Disk.sh 2020-05-24 20:24:34 +08:00
longpanda
487ffc6795 update Italian format 2020-05-23 21:33:36 +08:00
75 changed files with 4997 additions and 1509 deletions

12
.github/FUNDING.yml vendored Normal file
View File

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

View File

View File

@@ -199,5 +199,7 @@
INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b
5.11 INSTALL/tool/ash
https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH
SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b

View File

@@ -36,34 +36,24 @@
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
#include <Ventoy.h> #include <Ventoy.h>
UINTN g_iso_buf_size = 0;
BOOLEAN gMemdiskMode = FALSE;
BOOLEAN gDebugPrint = FALSE; BOOLEAN gDebugPrint = FALSE;
BOOLEAN gLoadIsoEfi = FALSE;
ventoy_ram_disk g_ramdisk_param; ventoy_ram_disk g_ramdisk_param;
ventoy_chain_head *g_chain; ventoy_chain_head *g_chain;
ventoy_img_chunk *g_chunk; ventoy_img_chunk *g_chunk;
UINT8 *g_os_param_reserved;
UINT32 g_img_chunk_num; UINT32 g_img_chunk_num;
ventoy_override_chunk *g_override_chunk; ventoy_override_chunk *g_override_chunk;
UINT32 g_override_chunk_num; UINT32 g_override_chunk_num;
ventoy_virt_chunk *g_virt_chunk; ventoy_virt_chunk *g_virt_chunk;
UINT32 g_virt_chunk_num; UINT32 g_virt_chunk_num;
vtoy_block_data gBlockData; vtoy_block_data gBlockData;
ventoy_sector_flag *g_sector_flag = NULL;
UINT32 g_sector_flag_num = 0;
static grub_env_get_pf grub_env_get = NULL; static grub_env_get_pf grub_env_get = NULL;
EFI_FILE_OPEN g_original_fopen = NULL;
EFI_FILE_CLOSE g_original_fclose = NULL;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL;
ventoy_grub_param_file_replace *g_file_replace_list = NULL; ventoy_grub_param_file_replace *g_file_replace_list = NULL;
ventoy_efi_file_replace g_efi_file_replace; ventoy_efi_file_replace g_efi_file_replace;
CHAR16 gFirstTryBootFile[256] = {0}; CHAR16 gFirstTryBootFile[256] = {0};
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
/* Boot filename */ /* Boot filename */
UINTN gBootFileStartIndex = 1; UINTN gBootFileStartIndex = 1;
CONST CHAR16 *gEfiBootFileName[] = CONST CHAR16 *gEfiBootFileName[] =
@@ -76,9 +66,6 @@ CONST CHAR16 *gEfiBootFileName[] =
L"\\efi\\boot\\bootx64.efi", L"\\efi\\boot\\bootx64.efi",
}; };
/* EFI block device vendor device path GUID */
EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID;
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...) VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...)
{ {
VA_LIST Marker; VA_LIST Marker;
@@ -204,6 +191,12 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain)
debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size); debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size);
debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr); debug("os_param->vtoy_img_location_addr=<0x%llx>", chain->os_param.vtoy_img_location_addr);
debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len); debug("os_param->vtoy_img_location_len=<%u>", chain->os_param.vtoy_img_location_len);
debug("os_param->vtoy_reserved=<%u %u %u %u>",
g_os_param_reserved[0],
g_os_param_reserved[1],
g_os_param_reserved[2],
g_os_param_reserved[3]
);
ventoy_debug_pause(); ventoy_debug_pause();
@@ -224,6 +217,70 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain)
ventoy_dump_virt_chunk(chain); ventoy_dump_virt_chunk(chain);
} }
static int ventoy_update_image_location(ventoy_os_param *param)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 chksum = 0;
unsigned int i;
unsigned int length;
UINTN address = 0;
void *buffer = NULL;
ventoy_image_location *location = NULL;
ventoy_image_disk_region *region = NULL;
ventoy_img_chunk *chunk = g_chunk;
length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer);
if (EFI_ERROR(Status) || NULL == buffer)
{
debug("Failed to allocate runtime pool %r\n", Status);
return 1;
}
address = (UINTN)buffer;
if (address % 4096)
{
address += 4096 - (address % 4096);
}
param->chksum = 0;
param->vtoy_img_location_addr = address;
param->vtoy_img_location_len = length;
/* update check sum */
for (i = 0; i < sizeof(ventoy_os_param); i++)
{
chksum += *((UINT8 *)param + i);
}
param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum);
location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr);
if (NULL == location)
{
return 0;
}
CopyMem(&location->guid, &param->guid, sizeof(ventoy_guid));
location->image_sector_size = 2048;
location->disk_sector_size = g_chain->disk_sector_size;
location->region_count = g_img_chunk_num;
region = location->regions;
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;
}
EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath) EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath)
{ {
EFI_HANDLE Handle = NULL; EFI_HANDLE Handle = NULL;
@@ -258,280 +315,6 @@ EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath
return Handle; return Handle;
} }
EFI_STATUS EFIAPI ventoy_block_io_reset
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
(VOID)This;
(VOID)ExtendedVerification;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
(
IN UINT64 Sector,
IN UINTN Count,
OUT 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;
UINT64 OverrideStart = 0;
UINT64 OverrideEnd= 0;
UINT8 *pCurBuf = (UINT8 *)Buffer;
ventoy_img_chunk *pchunk = g_chunk;
ventoy_override_chunk *pOverride = g_override_chunk;
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
debug("read 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->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
MapLba, secRead * 2048, pCurBuf);
if (EFI_ERROR(Status))
{
debug("Raw disk read block failed %r", Status);
return Status;
}
Count -= secRead;
Sector += secRead;
pCurBuf += secRead * 2048;
}
}
if (ReadStart > g_chain->real_img_size_in_bytes)
{
return EFI_SUCCESS;
}
/* override data */
pCurBuf = (UINT8 *)Buffer;
for (i = 0; i < g_override_chunk_num; i++, pOverride++)
{
OverrideStart = pOverride->img_offset;
OverrideEnd = pOverride->img_offset + pOverride->override_size;
if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd)
{
continue;
}
if (ReadStart <= OverrideStart)
{
if (ReadEnd <= OverrideEnd)
{
CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);
}
else
{
CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size);
}
}
else
{
if (ReadEnd <= OverrideEnd)
{
CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);
}
else
{
CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart);
}
}
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
//debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
(VOID)This;
(VOID)MediaId;
CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize);
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_block_io_read
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
UINT32 i = 0;
UINT32 j = 0;
UINT32 lbacount = 0;
UINT32 secNum = 0;
UINT64 offset = 0;
EFI_LBA curlba = 0;
EFI_LBA lastlba = 0;
UINT8 *lastbuffer;
ventoy_sector_flag *cur_flag;
ventoy_virt_chunk *node;
//debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
secNum = BufferSize / 2048;
offset = Lba * 2048;
if (offset + BufferSize < g_chain->real_img_size_in_bytes)
{
return ventoy_read_iso_sector(Lba, secNum, Buffer);
}
if (secNum > g_sector_flag_num)
{
cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag));
if (NULL == cur_flag)
{
return EFI_OUT_OF_RESOURCES;
}
FreePool(g_sector_flag);
g_sector_flag = cur_flag;
g_sector_flag_num = secNum;
}
for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
{
cur_flag->flag = 0;
for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
{
if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
{
CopyMem((UINT8 *)Buffer + j * 2048,
(char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
2048);
cur_flag->flag = 1;
break;
}
else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
{
cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
cur_flag->flag = 2;
break;
}
}
}
for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
{
if (cur_flag->flag == 2)
{
if (lastlba == 0)
{
lastbuffer = (UINT8 *)Buffer + j * 2048;
lastlba = cur_flag->remap_lba;
lbacount = 1;
}
else if (lastlba + lbacount == cur_flag->remap_lba)
{
lbacount++;
}
else
{
ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
lastbuffer = (UINT8 *)Buffer + j * 2048;
lastlba = cur_flag->remap_lba;
lbacount = 1;
}
}
}
if (lbacount > 0)
{
ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_block_io_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;
return EFI_WRITE_PROTECTED;
}
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
{
(VOID)This;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
{
UINTN NameLen = 0;
UINT8 TmpBuf[128] = {0};
VENDOR_DEVICE_PATH *venPath = NULL;
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
venPath->Header.Type = HARDWARE_DEVICE_PATH;
venPath->Header.SubType = HW_VENDOR_DP;
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
venPath->Header.Length[1] = 0;
CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID) EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
{ {
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
@@ -545,7 +328,7 @@ EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
return Status; return Status;
} }
EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID) EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID)
{ {
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
EFI_GUID VarGuid = VENTOY_GUID; EFI_GUID VarGuid = VENTOY_GUID;
@@ -559,7 +342,7 @@ EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID)
} }
EFI_STATUS EFIAPI ventoy_set_variable(VOID) EFI_STATUS EFIAPI ventoy_save_variable(VOID)
{ {
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
EFI_GUID VarGuid = VENTOY_GUID; EFI_GUID VarGuid = VENTOY_GUID;
@@ -585,56 +368,7 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID)
return Status; return Status;
} }
STATIC EFI_STATUS EFIAPI ventoy_load_image
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo);
ventoy_fill_device_path();
gBlockData.Media.BlockSize = 2048;
gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
gBlockData.Media.ReadOnly = TRUE;
gBlockData.Media.MediaPresent = 1;
gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
pBlockIo->Media = &(gBlockData.Media);
pBlockIo->Reset = ventoy_block_io_reset;
if (gMemdiskMode)
{
pBlockIo->ReadBlocks = ventoy_block_io_ramdisk_read;
}
else
{
pBlockIo->ReadBlocks = ventoy_block_io_read;
}
pBlockIo->WriteBlocks = ventoy_block_io_write;
pBlockIo->FlushBlocks = ventoy_block_io_flush;
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
&gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
&gEfiDevicePathProtocolGuid, gBlockData.Path,
NULL);
debug("Install protocol %r", Status);
if (EFI_ERROR(Status))
{
return Status;
}
Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, 1);
debug("Connect controller %r", Status);
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_load_image
( (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath,
@@ -745,156 +479,6 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle)
} }
} }
STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle)
{
UINTN i = 0;
UINTN Count = 0;
EFI_HANDLE Parent = NULL;
EFI_HANDLE *Handles = NULL;
EFI_STATUS Status = EFI_SUCCESS;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
NULL, &Count, &Handles);
if (EFI_ERROR(Status))
{
return Status;
}
debug("ventoy_find_iso_disk_fs fs count:%u", Count);
for (i = 0; i < Count; i++)
{
Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
if (EFI_ERROR(Status))
{
continue;
}
Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid,
(VOID **)&pDevPath,
ImageHandle,
Handles[i],
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(Status))
{
debug("Failed to open device path protocol %r", Status);
continue;
}
debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE));
Parent = ventoy_get_parent_handle(pDevPath);
if (Parent == gBlockData.RawBlockIoHandle)
{
debug("Find ventoy disk fs");
gBlockData.DiskFsHandle = Handles[i];
gBlockData.pDiskFs = pFile;
gBlockData.pDiskFsDevPath = pDevPath;
break;
}
}
FreePool(Handles);
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle)
{
EFI_HANDLE Image = NULL;
EFI_STATUS Status = EFI_SUCCESS;
CHAR16 LogVar[4] = L"5";
Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
gIso9660EfiDriverPath,
sizeof(gIso9660EfiDriverPath),
&Image);
debug("load iso efi driver status:%r", Status);
if (gDebugPrint)
{
gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(LogVar), LogVar);
}
gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(LogVar), LogVar);
gBlockData.IsoDriverImage = Image;
Status = gBS->StartImage(Image, NULL, NULL);
debug("Start iso efi driver status:%r", Status);
return EFI_SUCCESS;
}
static int ventoy_update_image_location(ventoy_os_param *param)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 chksum = 0;
unsigned int i;
unsigned int length;
UINTN address = 0;
void *buffer = NULL;
ventoy_image_location *location = NULL;
ventoy_image_disk_region *region = NULL;
ventoy_img_chunk *chunk = g_chunk;
length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer);
if (EFI_ERROR(Status) || NULL == buffer)
{
debug("Failed to allocate runtime pool %r\n", Status);
return 1;
}
address = (UINTN)buffer;
if (address % 4096)
{
address += 4096 - (address % 4096);
}
param->chksum = 0;
param->vtoy_img_location_addr = address;
param->vtoy_img_location_len = length;
/* update check sum */
for (i = 0; i < sizeof(ventoy_os_param); i++)
{
chksum += *((UINT8 *)param + i);
}
param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum);
location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr);
if (NULL == location)
{
return 0;
}
CopyMem(&location->guid, &param->guid, sizeof(ventoy_guid));
location->image_sector_size = 2048;
location->disk_sector_size = g_chain->disk_sector_size;
location->region_count = g_img_chunk_num;
region = location->regions;
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;
}
STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
{ {
UINT32 i = 0; UINT32 i = 0;
@@ -923,11 +507,6 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
gDebugPrint = TRUE; gDebugPrint = TRUE;
} }
if (StrStr(pCmdLine, L"isoefi=on"))
{
gLoadIsoEfi = TRUE;
}
pPos = StrStr(pCmdLine, L"FirstTry=@"); pPos = StrStr(pCmdLine, L"FirstTry=@");
if (pPos) if (pPos)
{ {
@@ -998,6 +577,14 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset);
g_virt_chunk_num = g_chain->virt_chunk_num; g_virt_chunk_num = g_chain->virt_chunk_num;
g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved);
/* Workaround for Windows & ISO9660 */
if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0)
{
g_fixup_iso9660_secover_enable = TRUE;
}
for (i = 0; i < sizeof(ventoy_os_param); i++) for (i = 0; i < sizeof(ventoy_os_param); i++)
{ {
chksum += *((UINT8 *)(&(g_chain->os_param)) + i); chksum += *((UINT8 *)(&(g_chain->os_param)) + i);
@@ -1020,82 +607,28 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS EFIAPI ventoy_wrapper_file_open EFI_STATUS EFIAPI ventoy_clean_env(VOID)
(
EFI_FILE_HANDLE This,
EFI_FILE_HANDLE *New,
CHAR16 *Name,
UINT64 Mode,
UINT64 Attributes
)
{ {
UINT32 i = 0; FreePool(g_sector_flag);
UINT32 j = 0; g_sector_flag_num = 0;
UINT64 Sectors = 0;
EFI_STATUS Status = EFI_SUCCESS;
CHAR8 TmpName[256];
ventoy_virt_chunk *virt = NULL;
Status = g_original_fopen(This, New, Name, Mode, Attributes); gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
if (EFI_ERROR(Status))
gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
&gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
&gEfiDevicePathProtocolGuid, gBlockData.Path,
NULL);
ventoy_delete_variable();
if (g_chain->os_param.vtoy_img_location_addr)
{ {
return Status; FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr);
} }
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC && return EFI_SUCCESS;
g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
{
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
for (j = 0; j < 4; j++)
{
if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName))
{
g_original_fclose(*New);
*New = &g_efi_file_replace.WrapperHandle;
ventoy_wrapper_file_procotol(*New);
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start;
g_efi_file_replace.FileSizeBytes = Sectors * 2048;
if (gDebugPrint)
{
debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048);
sleep(3);
} }
return Status;
}
}
}
return Status;
}
EFI_STATUS EFIAPI ventoy_wrapper_open_volume
(
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
OUT EFI_FILE_PROTOCOL **Root
)
{
EFI_STATUS Status = EFI_SUCCESS;
Status = g_original_open_volume(This, Root);
if (!EFI_ERROR(Status))
{
g_original_fopen = (*Root)->Open;
g_original_fclose = (*Root)->Close;
(*Root)->Open = ventoy_wrapper_file_open;
}
return Status;
}
EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
{ {
UINTN t = 0; UINTN t = 0;
@@ -1179,7 +712,7 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC)
{ {
g_original_open_volume = pFile->OpenVolume; ventoy_wrapper_push_openvolume(pFile->OpenVolume);
pFile->OpenVolume = ventoy_wrapper_open_volume; pFile->OpenVolume = ventoy_wrapper_open_volume;
} }
@@ -1210,74 +743,6 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS EFIAPI ventoy_clean_env(VOID)
{
FreePool(g_sector_flag);
g_sector_flag_num = 0;
if (gLoadIsoEfi && gBlockData.IsoDriverImage)
{
gBS->UnloadImage(gBlockData.IsoDriverImage);
}
gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
&gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
&gEfiDevicePathProtocolGuid, gBlockData.Path,
NULL);
ventoy_delete_variable();
if (g_chain->os_param.vtoy_img_location_addr)
{
FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr);
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_ramdisk_boot(IN EFI_HANDLE ImageHandle)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_RAM_DISK_PROTOCOL *RamDisk = NULL;
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
debug("RamDisk Boot ...");
Status = gBS->LocateProtocol(&gEfiRamDiskProtocolGuid, NULL, (VOID **)&RamDisk);
if (EFI_ERROR(Status))
{
debug("Failed to locate ramdisk protocol %r", Status);
return Status;
}
debug("Locate RamDisk Protocol %r ...", Status);
Status = RamDisk->Register((UINTN)g_chain, (UINT64)g_iso_buf_size, &gEfiVirtualCdGuid, NULL, &DevicePath);
if (EFI_ERROR(Status))
{
debug("Failed to register ramdisk %r", Status);
return Status;
}
debug("Register RamDisk %r ...", Status);
debug("RamDisk DevicePath:<%s> ...", ConvertDevicePathToText(DevicePath, FALSE, FALSE));
ventoy_debug_pause();
gBlockData.Path = DevicePath;
gBlockData.DevicePathCompareLen = GetDevicePathSize(DevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
Status = ventoy_boot(ImageHandle);
if (EFI_NOT_FOUND == Status)
{
gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
sleep(300);
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI VentoyEfiMain EFI_STATUS EFIAPI VentoyEfiMain
( (
@@ -1309,26 +774,14 @@ EFI_STATUS EFIAPI VentoyEfiMain
ventoy_install_blockio(ImageHandle, g_iso_buf_size); ventoy_install_blockio(ImageHandle, g_iso_buf_size);
Status = ventoy_boot(ImageHandle); Status = ventoy_boot(ImageHandle);
if (EFI_NOT_FOUND == Status)
{
gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
sleep(300);
}
ventoy_del_ramdisk_param(); ventoy_delete_ramdisk_param();
} }
else else
{ {
ventoy_set_variable(); ventoy_save_variable();
ventoy_find_iso_disk(ImageHandle); ventoy_find_iso_disk(ImageHandle);
if (gLoadIsoEfi)
{
ventoy_find_iso_disk_fs(ImageHandle);
ventoy_load_isoefi_driver(ImageHandle);
}
ventoy_debug_pause(); ventoy_debug_pause();
ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes);
@@ -1336,26 +789,15 @@ EFI_STATUS EFIAPI VentoyEfiMain
ventoy_debug_pause(); ventoy_debug_pause();
Status = ventoy_boot(ImageHandle); Status = ventoy_boot(ImageHandle);
if (EFI_NOT_FOUND == Status)
{
if (!gLoadIsoEfi)
{
gLoadIsoEfi = TRUE;
ventoy_find_iso_disk_fs(ImageHandle);
ventoy_load_isoefi_driver(ImageHandle);
Status = ventoy_boot(ImageHandle); ventoy_clean_env();
} }
if (EFI_NOT_FOUND == Status) if (EFI_NOT_FOUND == Status)
{ {
gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
sleep(60); sleep(30);
}
}
ventoy_clean_env();
} }
ventoy_clear_input(); ventoy_clear_input();
@@ -1364,4 +806,3 @@ EFI_STATUS EFIAPI VentoyEfiMain
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@@ -199,10 +199,8 @@ typedef struct vtoy_block_data
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
EFI_HANDLE IsoDriverImage;
}vtoy_block_data; }vtoy_block_data;
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi"
#define debug(expr, ...) if (gDebugPrint) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__) #define debug(expr, ...) if (gDebugPrint) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
#define trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__) #define trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
@@ -254,6 +252,14 @@ typedef struct ventoy_ram_disk
UINT64 DiskSize; UINT64 DiskSize;
}ventoy_ram_disk; }ventoy_ram_disk;
typedef struct ventoy_iso9660_override
{
UINT32 first_sector;
UINT32 first_sector_be;
UINT32 size;
UINT32 size_be;
}ventoy_iso9660_override;
#pragma pack() #pragma pack()
@@ -282,7 +288,6 @@ typedef struct ventoy_system_wrapper
bs->func = wrapper.New##func;\ bs->func = wrapper.New##func;\
} }
extern ventoy_efi_file_replace g_efi_file_replace;
extern BOOLEAN gDebugPrint; extern BOOLEAN gDebugPrint;
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...); VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID); EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
@@ -296,5 +301,30 @@ EFI_STATUS EFIAPI ventoy_block_io_read
OUT VOID *Buffer OUT VOID *Buffer
); );
extern ventoy_chain_head *g_chain;
extern ventoy_img_chunk *g_chunk;
extern UINT32 g_img_chunk_num;
extern ventoy_override_chunk *g_override_chunk;
extern UINT32 g_override_chunk_num;
extern ventoy_virt_chunk *g_virt_chunk;
extern UINT32 g_virt_chunk_num;
extern vtoy_block_data gBlockData;
extern ventoy_efi_file_replace g_efi_file_replace;
extern ventoy_sector_flag *g_sector_flag;
extern UINT32 g_sector_flag_num;
extern BOOLEAN gMemdiskMode;
extern UINTN g_iso_buf_size;
extern ventoy_grub_param_file_replace *g_file_replace_list;
extern BOOLEAN g_fixup_iso9660_secover_enable;
EFI_STATUS EFIAPI ventoy_wrapper_open_volume
(
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
OUT EFI_FILE_PROTOCOL **Root
);
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize);
EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume);
#endif #endif

View File

@@ -29,6 +29,7 @@
Ventoy.h Ventoy.h
Ventoy.c Ventoy.c
VentoyDebug.c VentoyDebug.c
VentoyProtocol.c
[Packages] [Packages]
MdePkg/MdePkg.dec MdePkg/MdePkg.dec

View File

@@ -0,0 +1,631 @@
/******************************************************************************
* Ventoy.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 <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/LoadedImage.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/RamDisk.h>
#include <Protocol/SimpleFileSystem.h>
#include <Ventoy.h>
UINTN g_iso_buf_size = 0;
BOOLEAN gMemdiskMode = FALSE;
ventoy_sector_flag *g_sector_flag = NULL;
UINT32 g_sector_flag_num = 0;
EFI_FILE_OPEN g_original_fopen = NULL;
EFI_FILE_CLOSE g_original_fclose = NULL;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL;
/* EFI block device vendor device path GUID */
EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID;
#define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152
BOOLEAN g_fixup_iso9660_secover_enable = FALSE;
BOOLEAN g_fixup_iso9660_secover_start = FALSE;
UINT64 g_fixup_iso9660_secover_1st_secs = 0;
UINT64 g_fixup_iso9660_secover_cur_secs = 0;
UINT64 g_fixup_iso9660_secover_tot_secs = 0;
EFI_STATUS EFIAPI ventoy_block_io_reset
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
(VOID)This;
(VOID)ExtendedVerification;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
(
IN UINT64 Sector,
IN UINTN Count,
OUT 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;
UINT64 OverrideStart = 0;
UINT64 OverrideEnd= 0;
UINT8 *pCurBuf = (UINT8 *)Buffer;
ventoy_img_chunk *pchunk = g_chunk;
ventoy_override_chunk *pOverride = g_override_chunk;
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo;
debug("read 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->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId,
MapLba, secRead * 2048, pCurBuf);
if (EFI_ERROR(Status))
{
debug("Raw disk read block failed %r", Status);
return Status;
}
Count -= secRead;
Sector += secRead;
pCurBuf += secRead * 2048;
}
}
if (ReadStart > g_chain->real_img_size_in_bytes)
{
return EFI_SUCCESS;
}
/* override data */
pCurBuf = (UINT8 *)Buffer;
for (i = 0; i < g_override_chunk_num; i++, pOverride++)
{
OverrideStart = pOverride->img_offset;
OverrideEnd = pOverride->img_offset + pOverride->override_size;
if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd)
{
continue;
}
if (ReadStart <= OverrideStart)
{
if (ReadEnd <= OverrideEnd)
{
CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);
}
else
{
CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size);
}
}
else
{
if (ReadEnd <= OverrideEnd)
{
CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);
}
else
{
CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart);
}
}
if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) &&
pOverride->override_size == sizeof(ventoy_iso9660_override))
{
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)pOverride->override_data;
if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW)
{
g_fixup_iso9660_secover_start = TRUE;
g_fixup_iso9660_secover_cur_secs = 0;
}
}
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
//debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
(VOID)This;
(VOID)MediaId;
CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize);
return EFI_SUCCESS;
}
EFI_LBA EFIAPI ventoy_fixup_iso9660_sector(IN EFI_LBA Lba, UINT32 secNum)
{
UINT32 i = 0;
if (g_fixup_iso9660_secover_cur_secs > 0)
{
Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
g_fixup_iso9660_secover_cur_secs += secNum;
if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
{
g_fixup_iso9660_secover_start = FALSE;
goto end;
}
}
else
{
ventoy_iso9660_override *dirent;
ventoy_override_chunk *pOverride;
for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
{
dirent = (ventoy_iso9660_override *)pOverride->override_data;
if (Lba == dirent->first_sector)
{
g_fixup_iso9660_secover_start = FALSE;
goto end;
}
}
if (g_fixup_iso9660_secover_start)
{
for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
{
dirent = (ventoy_iso9660_override *)pOverride->override_data;
if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector)
{
g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048;
g_fixup_iso9660_secover_cur_secs = secNum;
if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
{
g_fixup_iso9660_secover_start = FALSE;
}
Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
goto end;
}
}
}
}
end:
return Lba;
}
EFI_STATUS EFIAPI ventoy_block_io_read
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
UINT32 i = 0;
UINT32 j = 0;
UINT32 lbacount = 0;
UINT32 secNum = 0;
UINT64 offset = 0;
EFI_LBA curlba = 0;
EFI_LBA lastlba = 0;
UINT8 *lastbuffer;
ventoy_sector_flag *cur_flag;
ventoy_virt_chunk *node;
//debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
secNum = BufferSize / 2048;
/* Workaround for SSTR PE loader error */
if (g_fixup_iso9660_secover_start)
{
Lba = ventoy_fixup_iso9660_sector(Lba, secNum);
}
offset = Lba * 2048;
if (offset + BufferSize <= g_chain->real_img_size_in_bytes)
{
return ventoy_read_iso_sector(Lba, secNum, Buffer);
}
if (secNum > g_sector_flag_num)
{
cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag));
if (NULL == cur_flag)
{
return EFI_OUT_OF_RESOURCES;
}
FreePool(g_sector_flag);
g_sector_flag = cur_flag;
g_sector_flag_num = secNum;
}
for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
{
cur_flag->flag = 0;
for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
{
if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
{
CopyMem((UINT8 *)Buffer + j * 2048,
(char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
2048);
cur_flag->flag = 1;
break;
}
else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
{
cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
cur_flag->flag = 2;
break;
}
}
}
for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
{
if (cur_flag->flag == 2)
{
if (lastlba == 0)
{
lastbuffer = (UINT8 *)Buffer + j * 2048;
lastlba = cur_flag->remap_lba;
lbacount = 1;
}
else if (lastlba + lbacount == cur_flag->remap_lba)
{
lbacount++;
}
else
{
ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
lastbuffer = (UINT8 *)Buffer + j * 2048;
lastlba = cur_flag->remap_lba;
lbacount = 1;
}
}
}
if (lbacount > 0)
{
ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
}
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_block_io_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;
return EFI_WRITE_PROTECTED;
}
EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
{
(VOID)This;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
{
UINTN NameLen = 0;
UINT8 TmpBuf[128] = {0};
VENDOR_DEVICE_PATH *venPath = NULL;
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
venPath->Header.Type = HARDWARE_DEVICE_PATH;
venPath->Header.SubType = HW_VENDOR_DP;
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
venPath->Header.Length[1] = 0;
CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName)
{
UINTN i = 0;
UINTN Count = 0;
CHAR16 *DriverName = NULL;
EFI_HANDLE *Handles = NULL;
EFI_HANDLE DrvHandles[2] = { NULL };
EFI_STATUS Status = EFI_SUCCESS;
EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL;
EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL;
debug("ventoy_connect_driver <%s>...", DrvName);
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,
NULL, &Count, &Handles);
if (EFI_ERROR(Status))
{
return Status;
}
for (i = 0; i < Count; i++)
{
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol);
if (EFI_ERROR(Status))
{
continue;
}
Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName);
if (EFI_ERROR(Status) || NULL == DriverName)
{
continue;
}
if (StrStr(DriverName, DrvName))
{
debug("Find driver name2:<%s>: <%s>", DriverName, DrvName);
DrvHandles[0] = Handles[i];
break;
}
}
if (i < Count)
{
Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
debug("Connect partition driver:<%r>", Status);
goto end;
}
debug("%s NOT found, now try COMPONENT_NAME", DrvName);
Count = 0;
FreePool(Handles);
Handles = NULL;
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,
NULL, &Count, &Handles);
if (EFI_ERROR(Status))
{
return Status;
}
for (i = 0; i < Count; i++)
{
Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol);
if (EFI_ERROR(Status))
{
continue;
}
Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName);
if (EFI_ERROR(Status))
{
continue;
}
if (StrStr(DriverName, DrvName))
{
debug("Find driver name:<%s>: <%s>", DriverName, DrvName);
DrvHandles[0] = Handles[i];
break;
}
}
if (i < Count)
{
Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE);
debug("Connect partition driver:<%r>", Status);
goto end;
}
Status = EFI_NOT_FOUND;
end:
FreePool(Handles);
return Status;
}
EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo);
ventoy_fill_device_path();
gBlockData.Media.BlockSize = 2048;
gBlockData.Media.LastBlock = ImgSize / 2048 - 1;
gBlockData.Media.ReadOnly = TRUE;
gBlockData.Media.MediaPresent = 1;
gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1;
pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
pBlockIo->Media = &(gBlockData.Media);
pBlockIo->Reset = ventoy_block_io_reset;
pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read;
pBlockIo->WriteBlocks = ventoy_block_io_write;
pBlockIo->FlushBlocks = ventoy_block_io_flush;
Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle,
&gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
&gEfiDevicePathProtocolGuid, gBlockData.Path,
NULL);
debug("Install protocol %r %p", Status, gBlockData.Handle);
if (EFI_ERROR(Status))
{
return Status;
}
Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver");
debug("Connect disk IO driver %r", Status);
ventoy_debug_pause();
Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver");
debug("Connect partition driver %r", Status);
if (EFI_ERROR(Status))
{
Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, TRUE);
debug("Connect all controller %r", Status);
}
ventoy_debug_pause();
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI ventoy_wrapper_file_open
(
EFI_FILE_HANDLE This,
EFI_FILE_HANDLE *New,
CHAR16 *Name,
UINT64 Mode,
UINT64 Attributes
)
{
UINT32 i = 0;
UINT32 j = 0;
UINT64 Sectors = 0;
EFI_STATUS Status = EFI_SUCCESS;
CHAR8 TmpName[256];
ventoy_virt_chunk *virt = NULL;
Status = g_original_fopen(This, New, Name, Mode, Attributes);
if (EFI_ERROR(Status))
{
return Status;
}
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC &&
g_file_replace_list->new_file_virtual_id < g_virt_chunk_num)
{
AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name);
for (j = 0; j < 4; j++)
{
if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName))
{
g_original_fclose(*New);
*New = &g_efi_file_replace.WrapperHandle;
ventoy_wrapper_file_procotol(*New);
virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id;
Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start);
g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start;
g_efi_file_replace.FileSizeBytes = Sectors * 2048;
if (gDebugPrint)
{
debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name,
g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048);
sleep(3);
}
return Status;
}
}
}
return Status;
}
EFI_STATUS EFIAPI ventoy_wrapper_open_volume
(
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
OUT EFI_FILE_PROTOCOL **Root
)
{
EFI_STATUS Status = EFI_SUCCESS;
Status = g_original_open_volume(This, Root);
if (!EFI_ERROR(Status))
{
g_original_fopen = (*Root)->Open;
g_original_fclose = (*Root)->Close;
(*Root)->Open = ventoy_wrapper_file_open;
}
return Status;
}
EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume)
{
g_original_open_volume = OpenVolume;
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,491 @@
/* test.c -- The test command.. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/fs.h>
#include <grub/device.h>
#include <grub/file.h>
#include <grub/command.h>
#include <grub/i18n.h>
GRUB_MOD_LICENSE ("GPLv3+");
static int g_test_case_insensitive = 0;
/* A simple implementation for signed numbers. */
static int
grub_strtosl (char *arg, char **end, int base)
{
if (arg[0] == '-')
return -grub_strtoul (arg + 1, end, base);
return grub_strtoul (arg, end, base);
}
/* Context for test_parse. */
struct test_parse_ctx
{
int invert;
int or, and;
int file_exists;
struct grub_dirhook_info file_info;
char *filename;
};
/* Take care of discarding and inverting. */
static void
update_val (int val, struct test_parse_ctx *ctx)
{
ctx->and = ctx->and && (ctx->invert ? ! val : val);
ctx->invert = 0;
}
/* A hook for iterating directories. */
static int
find_file (const char *cur_filename, const struct grub_dirhook_info *info,
void *data)
{
int case_insensitive = 0;
struct test_parse_ctx *ctx = data;
if (g_test_case_insensitive || info->case_insensitive)
case_insensitive = 1;
if ((case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename)
: grub_strcmp (cur_filename, ctx->filename)) == 0)
{
ctx->file_info = *info;
ctx->file_exists = 1;
return 1;
}
return 0;
}
/* Check if file exists and fetch its information. */
static void
get_fileinfo (char *path, struct test_parse_ctx *ctx)
{
char *pathname;
char *device_name;
grub_fs_t fs;
grub_device_t dev;
ctx->file_exists = 0;
device_name = grub_file_get_device_name (path);
dev = grub_device_open (device_name);
if (! dev)
{
grub_free (device_name);
return;
}
fs = grub_fs_probe (dev);
if (! fs)
{
grub_free (device_name);
grub_device_close (dev);
return;
}
pathname = grub_strchr (path, ')');
if (! pathname)
pathname = path;
else
pathname++;
/* Remove trailing '/'. */
while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
pathname[grub_strlen (pathname) - 1] = 0;
/* Split into path and filename. */
ctx->filename = grub_strrchr (pathname, '/');
if (! ctx->filename)
{
path = grub_strdup ("/");
ctx->filename = pathname;
}
else
{
ctx->filename++;
path = grub_strdup (pathname);
path[ctx->filename - pathname] = 0;
}
/* It's the whole device. */
if (! *pathname)
{
ctx->file_exists = 1;
grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info));
/* Root is always a directory. */
ctx->file_info.dir = 1;
/* Fetch writing time. */
ctx->file_info.mtimeset = 0;
if (fs->fs_mtime)
{
if (! fs->fs_mtime (dev, &ctx->file_info.mtime))
ctx->file_info.mtimeset = 1;
grub_errno = GRUB_ERR_NONE;
}
}
else
(fs->fs_dir) (dev, path, find_file, ctx);
grub_device_close (dev);
grub_free (path);
grub_free (device_name);
}
/* Parse a test expression starting from *argn. */
static int
test_parse (char **args, int *argn, int argc)
{
struct test_parse_ctx ctx = {
.and = 1,
.or = 0,
.invert = 0
};
/* Here we have the real parsing. */
while (*argn < argc)
{
/* First try 3 argument tests. */
if (*argn + 2 < argc)
{
/* String tests. */
if (grub_strcmp (args[*argn + 1], "=") == 0
|| grub_strcmp (args[*argn + 1], "==") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0,
&ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "!=") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0,
&ctx);
(*argn) += 3;
continue;
}
/* GRUB extension: lexicographical sorting. */
if (grub_strcmp (args[*argn + 1], "<") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0,
&ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "<=") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0,
&ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], ">") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0,
&ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], ">=") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0,
&ctx);
(*argn) += 3;
continue;
}
/* Number tests. */
if (grub_strcmp (args[*argn + 1], "-eq") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
== grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
>= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
> grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-le") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
<= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
< grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
{
update_val (grub_strtosl (args[*argn], 0, 0)
!= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
(*argn) += 3;
continue;
}
/* GRUB extension: compare numbers skipping prefixes.
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
if (grub_strcmp (args[*argn + 1], "-pgt") == 0
|| grub_strcmp (args[*argn + 1], "-plt") == 0)
{
int i;
/* Skip common prefix. */
for (i = 0; args[*argn][i] == args[*argn + 2][i]
&& args[*argn][i]; i++);
/* Go the digits back. */
i--;
while (grub_isdigit (args[*argn][i]) && i > 0)
i--;
i++;
if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
update_val (grub_strtoul (args[*argn] + i, 0, 0)
> grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
else
update_val (grub_strtoul (args[*argn] + i, 0, 0)
< grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
(*argn) += 3;
continue;
}
/* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
will be added to the first mtime. */
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
|| grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
{
struct grub_dirhook_info file1;
int file1exists;
int bias = 0;
/* Fetch fileinfo. */
get_fileinfo (args[*argn], &ctx);
file1 = ctx.file_info;
file1exists = ctx.file_exists;
get_fileinfo (args[*argn + 2], &ctx);
if (args[*argn + 1][3])
bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
update_val ((file1exists && ! ctx.file_exists)
|| (file1.mtimeset && ctx.file_info.mtimeset
&& file1.mtime + bias > ctx.file_info.mtime),
&ctx);
else
update_val ((! file1exists && ctx.file_exists)
|| (file1.mtimeset && ctx.file_info.mtimeset
&& file1.mtime + bias < ctx.file_info.mtime),
&ctx);
(*argn) += 3;
continue;
}
}
/* Two-argument tests. */
if (*argn + 1 < argc)
{
/* File tests. */
if (grub_strcmp (args[*argn], "-d") == 0)
{
get_fileinfo (args[*argn + 1], &ctx);
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-D") == 0)
{
g_test_case_insensitive = 1;
get_fileinfo (args[*argn + 1], &ctx);
g_test_case_insensitive = 0;
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-e") == 0)
{
get_fileinfo (args[*argn + 1], &ctx);
update_val (ctx.file_exists, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-E") == 0)
{
g_test_case_insensitive = 1;
get_fileinfo (args[*argn + 1], &ctx);
g_test_case_insensitive = 0;
update_val (ctx.file_exists, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-f") == 0)
{
get_fileinfo (args[*argn + 1], &ctx);
/* FIXME: check for other types. */
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-F") == 0)
{
g_test_case_insensitive = 1;
get_fileinfo (args[*argn + 1], &ctx);
g_test_case_insensitive = 0;
/* FIXME: check for other types. */
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-s") == 0)
{
grub_file_t file;
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
update_val (file && (grub_file_size (file) != 0), &ctx);
if (file)
grub_file_close (file);
grub_errno = GRUB_ERR_NONE;
(*argn) += 2;
continue;
}
/* String tests. */
if (grub_strcmp (args[*argn], "-n") == 0)
{
update_val (args[*argn + 1][0], &ctx);
(*argn) += 2;
continue;
}
if (grub_strcmp (args[*argn], "-z") == 0)
{
update_val (! args[*argn + 1][0], &ctx);
(*argn) += 2;
continue;
}
}
/* Special modifiers. */
/* End of expression. return to parent. */
if (grub_strcmp (args[*argn], ")") == 0)
{
(*argn)++;
return ctx.or || ctx.and;
}
/* Recursively invoke if parenthesis. */
if (grub_strcmp (args[*argn], "(") == 0)
{
(*argn)++;
update_val (test_parse (args, argn, argc), &ctx);
continue;
}
if (grub_strcmp (args[*argn], "!") == 0)
{
ctx.invert = ! ctx.invert;
(*argn)++;
continue;
}
if (grub_strcmp (args[*argn], "-a") == 0)
{
(*argn)++;
continue;
}
if (grub_strcmp (args[*argn], "-o") == 0)
{
ctx.or = ctx.or || ctx.and;
ctx.and = 1;
(*argn)++;
continue;
}
/* No test found. Interpret if as just a string. */
update_val (args[*argn][0], &ctx);
(*argn)++;
}
return ctx.or || ctx.and;
}
static grub_err_t
grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int argn = 0;
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
argc--;
return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
: grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
}
static grub_command_t cmd_1, cmd_2;
GRUB_MOD_INIT(test)
{
cmd_1 = grub_register_command ("[", grub_cmd_test,
N_("EXPRESSION ]"), N_("Evaluate an expression."));
cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
cmd_2 = grub_register_command ("test", grub_cmd_test,
N_("EXPRESSION"), N_("Evaluate an expression."));
cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
}
GRUB_MOD_FINI(test)
{
grub_unregister_command (cmd_1);
grub_unregister_command (cmd_2);
}

View File

@@ -117,6 +117,8 @@ struct grub_fshelp_find_file_iter_ctx
enum grub_fshelp_filetype *foundtype; enum grub_fshelp_filetype *foundtype;
}; };
int g_ventoy_case_insensitive = 0;
/* Helper for grub_fshelp_find_file. */ /* Helper for grub_fshelp_find_file. */
static int static int
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
@@ -124,6 +126,11 @@ find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
{ {
struct grub_fshelp_find_file_iter_ctx *ctx = data; struct grub_fshelp_find_file_iter_ctx *ctx = data;
if (g_ventoy_case_insensitive)
{
filetype |= GRUB_FSHELP_CASE_INSENSITIVE;
}
if (filetype == GRUB_FSHELP_UNKNOWN || if (filetype == GRUB_FSHELP_UNKNOWN ||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE) ((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
? grub_strcasecmp (ctx->name, filename) ? grub_strcasecmp (ctx->name, filename)

View File

@@ -32,6 +32,7 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
static int g_ventoy_no_joliet = 0;
static grub_uint64_t g_ventoy_last_read_pos = 0; static grub_uint64_t g_ventoy_last_read_pos = 0;
static grub_uint64_t g_ventoy_last_read_offset = 0; static grub_uint64_t g_ventoy_last_read_offset = 0;
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0; static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
@@ -480,9 +481,11 @@ grub_iso9660_mount (grub_disk_t disk)
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
{ {
if (0 == g_ventoy_no_joliet) {
copy_voldesc = 1; copy_voldesc = 1;
data->joliet = 1; data->joliet = 1;
} }
}
if (copy_voldesc) if (copy_voldesc)
{ {
@@ -1108,6 +1111,11 @@ grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
return err; return err;
} }
void grub_iso9660_set_nojoliet(int nojoliet)
{
g_ventoy_no_joliet = nojoliet;
}
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file) grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file)
{ {
(void)file; (void)file;

View File

@@ -970,8 +970,6 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
} }
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
if (!info.dir)
info.size = node->inode.size;
grub_free (node); grub_free (node);
return ctx->hook (filename, &info, ctx->hook_data); return ctx->hook (filename, &info, ctx->hook_data);
} }

View File

@@ -27,7 +27,7 @@
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/ventoy.h> #include <grub/ventoy.h>
#define GRUB_CACHE_TIMEOUT 2 #define GRUB_CACHE_TIMEOUT 10
/* The last time the disk was used. */ /* The last time the disk was used. */
static grub_uint64_t grub_last_time = 0; static grub_uint64_t grub_last_time = 0;
@@ -412,16 +412,23 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector,
grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector, grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector,
grub_uint64_t size, grub_uint32_t log_sector_size) grub_uint64_t size, grub_uint32_t log_sector_size)
{ {
grub_uint64_t sizeshift;
ventoy_img_chunk *last_chunk = NULL; ventoy_img_chunk *last_chunk = NULL;
ventoy_img_chunk *new_chunk = NULL; ventoy_img_chunk *new_chunk = NULL;
ventoy_img_chunk_list *chunk_list = (ventoy_img_chunk_list *)chunklist; ventoy_img_chunk_list *chunk_list = (ventoy_img_chunk_list *)chunklist;
sizeshift = (size >> log_sector_size);
if (sizeshift == 0)
{
sizeshift = 1;
}
if (chunk_list->cur_chunk == 0) if (chunk_list->cur_chunk == 0)
{ {
chunk_list->chunk[0].img_start_sector = 0; chunk_list->chunk[0].img_start_sector = 0;
chunk_list->chunk[0].img_end_sector = (size >> 11) - 1; chunk_list->chunk[0].img_end_sector = (size >> 11) - 1;
chunk_list->chunk[0].disk_start_sector = sector; chunk_list->chunk[0].disk_start_sector = sector;
chunk_list->chunk[0].disk_end_sector = sector + (size >> log_sector_size) - 1; chunk_list->chunk[0].disk_end_sector = sector + sizeshift - 1;
chunk_list->cur_chunk = 1; chunk_list->cur_chunk = 1;
return 0; return 0;
} }
@@ -430,7 +437,7 @@ grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector,
if (last_chunk->disk_end_sector + 1 == sector) if (last_chunk->disk_end_sector + 1 == sector)
{ {
last_chunk->img_end_sector += (size >> 11); last_chunk->img_end_sector += (size >> 11);
last_chunk->disk_end_sector += (size >> log_sector_size); last_chunk->disk_end_sector += sizeshift;
return 0; return 0;
} }
@@ -452,7 +459,7 @@ grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector,
new_chunk->img_start_sector = last_chunk->img_end_sector + 1; new_chunk->img_start_sector = last_chunk->img_end_sector + 1;
new_chunk->img_end_sector = new_chunk->img_start_sector + (size >> 11) - 1; new_chunk->img_end_sector = new_chunk->img_start_sector + (size >> 11) - 1;
new_chunk->disk_start_sector = sector; new_chunk->disk_start_sector = sector;
new_chunk->disk_end_sector = sector + (size >> log_sector_size) - 1; new_chunk->disk_end_sector = sector + sizeshift - 1;
chunk_list->cur_chunk++; chunk_list->cur_chunk++;

View File

@@ -83,6 +83,29 @@ grub_file_t grub_memfile_open(const char *name)
return file; return file;
} }
int ventoy_check_file_exist(const char * fmt, ...)
{
va_list ap;
grub_file_t file;
char fullpath[256] = {0};
va_start (ap, fmt);
grub_vsnprintf(fullpath, 255, fmt, ap);
va_end (ap);
file = grub_file_open(fullpath, GRUB_FILE_TYPE_NONE);
if (!file)
{
grub_errno = 0;
return 0;
}
else
{
grub_file_close(file);
return 1;
}
}
grub_file_t grub_file_t
grub_file_open (const char *name, enum grub_file_type type) grub_file_open (const char *name, enum grub_file_type type)
{ {

View File

@@ -260,6 +260,45 @@ reclaim_module_space (void)
#endif #endif
} }
#ifndef GRUB_MACHINE_EFI
static int ventoy_legacy_limit_workaround(void)
{
grub_file_t file;
char *pos, *root;
char buf[128];
root = grub_strdup(grub_env_get("root"));
if (!root)
{
return 1;
}
pos = grub_strchr(root, ',');
if (pos) *pos = 0;
grub_snprintf(buf, sizeof(buf), "(%s,1)/ventoy/ventoy.disk.img.xz", root);
file = grub_file_open(buf, GRUB_FILE_TYPE_NONE);
if (file)
{
pos = grub_malloc(file->size);
if (pos)
{
grub_file_read(file, pos, file->size);
grub_snprintf(buf, sizeof(buf), "loopback ventoydisk mem:0x%lx:size:%lu",
(unsigned long)pos, (unsigned long)file->size);
grub_parser_execute(buf);
grub_env_set("prefix", "(ventoydisk)/grub");
}
grub_file_close(file);
}
grub_free(root);
return 0;
}
#endif
/* The main routine. */ /* The main routine. */
void __attribute__ ((noreturn)) void __attribute__ ((noreturn))
grub_main (void) grub_main (void)
@@ -293,6 +332,12 @@ grub_main (void)
grub_env_export ("root"); grub_env_export ("root");
grub_env_export ("prefix"); grub_env_export ("prefix");
#ifndef GRUB_MACHINE_EFI
if (0 == ventoy_check_file_exist("%s/grub.cfg", grub_env_get("prefix"))) {
ventoy_legacy_limit_workaround();
}
#endif
/* Reclaim space used for modules. */ /* Reclaim space used for modules. */
reclaim_module_space (); reclaim_module_space ();

View File

@@ -39,6 +39,9 @@ int g_ventoy_memdisk_mode = 0;
int g_ventoy_iso_raw = 0; int g_ventoy_iso_raw = 0;
int g_ventoy_iso_uefi_drv = 0; int g_ventoy_iso_uefi_drv = 0;
int g_ventoy_last_entry = 0; int g_ventoy_last_entry = 0;
int g_ventoy_suppress_esc = 0;
int g_ventoy_menu_esc = 0;
int g_ventoy_fn_mutex = 0;
/* Time to delay after displaying an error message about a default/fallback /* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */ entry failing to boot. */
@@ -591,7 +594,9 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
default_entry = get_entry_number (menu, "default"); default_entry = get_entry_number (menu, "default");
if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) { if (g_ventoy_suppress_esc)
default_entry = 1;
else if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) {
default_entry = g_ventoy_last_entry; default_entry = g_ventoy_last_entry;
} }
/* If DEFAULT_ENTRY is not within the menu entries, fall back to /* If DEFAULT_ENTRY is not within the menu entries, fall back to
@@ -776,7 +781,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
return current_entry; return current_entry;
case GRUB_TERM_ESC: case GRUB_TERM_ESC:
if (nested) if (nested && 0 == g_ventoy_suppress_esc)
{ {
menu_fini (); menu_fini ();
return -1; return -1;
@@ -798,15 +803,20 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
goto refresh; goto refresh;
case GRUB_TERM_KEY_F2: case GRUB_TERM_KEY_F2:
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F2_CMD"); cmdstr = grub_env_get("VTOY_F2_CMD");
if (cmdstr) if (cmdstr)
{ {
menu_fini (); menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr); grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh; goto refresh;
} }
}
break; break;
case GRUB_TERM_KEY_F3: case GRUB_TERM_KEY_F3:
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F3_CMD"); cmdstr = grub_env_get("VTOY_F3_CMD");
if (cmdstr) if (cmdstr)
{ {
@@ -814,24 +824,33 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
grub_script_execute_sourcecode(cmdstr); grub_script_execute_sourcecode(cmdstr);
goto refresh; goto refresh;
} }
}
break; break;
case GRUB_TERM_KEY_F4: case GRUB_TERM_KEY_F4:
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F4_CMD"); cmdstr = grub_env_get("VTOY_F4_CMD");
if (cmdstr) if (cmdstr)
{ {
menu_fini (); menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr); grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh; goto refresh;
} }
}
break; break;
case GRUB_TERM_KEY_F5: case GRUB_TERM_KEY_F5:
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F5_CMD"); cmdstr = grub_env_get("VTOY_F5_CMD");
if (cmdstr) if (cmdstr)
{ {
menu_fini (); menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr); grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh; goto refresh;
} }
}
break; break;
case GRUB_TERM_KEY_F6: case GRUB_TERM_KEY_F6:
cmdstr = grub_env_get("VTOY_F6_CMD"); cmdstr = grub_env_get("VTOY_F6_CMD");
@@ -950,11 +969,16 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
break; break;
g_ventoy_last_entry = boot_entry; 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)
continue; /* Menu is empty. */ continue; /* Menu is empty. */
if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RET", 8) == 0)
break;
grub_cls (); grub_cls ();
if (auto_boot) if (auto_boot)

View File

@@ -33,6 +33,7 @@
#include <grub/datetime.h> #include <grub/datetime.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/net.h> #include <grub/net.h>
#include <grub/misc.h>
#ifdef GRUB_MACHINE_EFI #ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h> #include <grub/efi/efi.h>
#endif #endif
@@ -49,12 +50,15 @@ initrd_info *g_initrd_img_list = NULL;
initrd_info *g_initrd_img_tail = NULL; initrd_info *g_initrd_img_tail = NULL;
int g_initrd_img_count = 0; int g_initrd_img_count = 0;
int g_valid_initrd_count = 0; int g_valid_initrd_count = 0;
int g_default_menu_mode = 0;
int g_filt_dot_underscore_file = 0; int g_filt_dot_underscore_file = 0;
static grub_file_t g_old_file; static grub_file_t g_old_file;
char g_iso_path[256];
char g_img_swap_tmp_buf[1024]; char g_img_swap_tmp_buf[1024];
img_info g_img_swap_tmp; img_info g_img_swap_tmp;
img_info *g_ventoy_img_list = NULL; img_info *g_ventoy_img_list = NULL;
int g_ventoy_img_count = 0; int g_ventoy_img_count = 0;
grub_device_t g_enum_dev = NULL; grub_device_t g_enum_dev = NULL;
@@ -64,6 +68,7 @@ img_iterator_node *g_img_iterator_tail = NULL;
grub_uint8_t g_ventoy_break_level = 0; grub_uint8_t g_ventoy_break_level = 0;
grub_uint8_t g_ventoy_debug_level = 0; grub_uint8_t g_ventoy_debug_level = 0;
grub_uint8_t g_ventoy_chain_type = 0;
grub_uint8_t *g_ventoy_cpio_buf = NULL; grub_uint8_t *g_ventoy_cpio_buf = NULL;
grub_uint32_t g_ventoy_cpio_size = 0; grub_uint32_t g_ventoy_cpio_size = 0;
cpio_newc_header *g_ventoy_initrd_head = NULL; cpio_newc_header *g_ventoy_initrd_head = NULL;
@@ -75,6 +80,10 @@ ventoy_guid g_ventoy_guid = VENTOY_GUID;
ventoy_img_chunk_list g_img_chunk_list; ventoy_img_chunk_list g_img_chunk_list;
int g_wimboot_enable = 0;
ventoy_img_chunk_list g_wimiso_chunk_list;
char *g_wimiso_path = NULL;
static char *g_tree_script_buf = NULL; static char *g_tree_script_buf = NULL;
static int g_tree_script_pos = 0; static int g_tree_script_pos = 0;
@@ -341,6 +350,44 @@ static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, cha
return rc; return rc;
} }
static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_file_t file;
(void)ctxt;
(void)argc;
(void)args;
g_wimboot_enable = 0;
grub_check_free(g_wimiso_path);
grub_check_free(g_wimiso_chunk_list.chunk);
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
if (!file)
{
return 0;
}
grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list));
g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
if (NULL == g_wimiso_chunk_list.chunk)
{
return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
}
g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM;
g_wimiso_chunk_list.cur_chunk = 0;
ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start);
g_wimboot_enable = 1;
g_wimiso_path = grub_strdup(args[0]);
grub_file_close(file);
return 0;
}
static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int rc = 1; int rc = 1;
@@ -387,6 +434,27 @@ static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int arg
return rc; return rc;
} }
static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
if (argc != 1)
{
return 1;
}
if (args[0][0] == '1')
{
grub_iso9660_set_nojoliet(1);
}
else
{
grub_iso9660_set_nojoliet(0);
}
return 0;
}
static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int i; int i;
@@ -659,6 +727,8 @@ static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirh
static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data)
{ {
int i = 0;
int type = 0;
int ignore = 0; int ignore = 0;
grub_size_t len; grub_size_t len;
img_info *img; img_info *img;
@@ -723,10 +793,25 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
else else
{ {
debug("Find a file %s\n", filename); debug("Find a file %s\n", filename);
if (len <= 4)
if ((len > 4) && (0 == grub_strcasecmp(filename + len - 4, ".iso")))
{ {
if (!ventoy_img_name_valid(filename, len)) return 0;
}
if (0 == grub_strcasecmp(filename + len - 4, ".iso"))
{
type = img_type_iso;
}
else if (g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim")))
{
type = img_type_wim;
}
else
{
return 0;
}
if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_')
{ {
return 0; return 0;
} }
@@ -734,8 +819,32 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
img = grub_zalloc(sizeof(img_info)); img = grub_zalloc(sizeof(img_info));
if (img) if (img)
{ {
img->type = type;
grub_snprintf(img->name, sizeof(img->name), "%s", filename); grub_snprintf(img->name, sizeof(img->name), "%s", filename);
grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, filename);
for (i = 0; i < (int)len; i++)
{
if (filename[i] == ' ' || filename[i] == '\t' || (0 == grub_isprint(filename[i])))
{
img->name[i] = '*';
img->unsupport = 1;
}
}
grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name);
img->size = info->size;
if (0 == img->size)
{
img->size = ventoy_grub_get_file_size("%s/%s", g_iso_path, img->path);
}
if (img->size < VTOY_FILT_MIN_FILE_SIZE)
{
debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size);
grub_free(img);
return 0;
}
if (g_ventoy_img_list) if (g_ventoy_img_list)
{ {
@@ -748,7 +857,6 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
g_ventoy_img_list = img; g_ventoy_img_list = img;
} }
img->size = info->size;
img->id = g_ventoy_img_count; img->id = g_ventoy_img_count;
img->parent = node; img->parent = node;
if (node && NULL == node->firstiso) if (node && NULL == node->firstiso)
@@ -767,10 +875,11 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
*((img_info **)(node->tail)) = img; *((img_info **)(node->tail)) = img;
g_ventoy_img_count++; g_ventoy_img_count++;
img->alias = ventoy_plugin_get_menu_alias(img->path);
debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count);
} }
} }
}
return 0; return 0;
} }
@@ -911,11 +1020,27 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
offset = node->parent->dirlen; offset = node->parent->dirlen;
} }
if (node != &g_img_iterator_head) if (node == &g_img_iterator_head)
{
if (g_default_menu_mode == 0)
{
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"menuentry \"%-10s [Return to ListView]\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n", "<--");
}
}
else
{ {
node->dir[node->dirlen - 1] = 0; node->dir[node->dirlen - 1] = 0;
g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"submenu \"%-10s [%s]\" {\n", "DIR", node->dir + offset); "submenu \"%-10s [%s]\" {\n",
"DIR", node->dir + offset);
vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"menuentry \"%-10s [../]\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n", "<--");
} }
while ((child = ventoy_get_min_child(node)) != NULL) while ((child = ventoy_get_min_child(node)) != NULL)
@@ -925,16 +1050,20 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
while ((img = ventoy_get_min_iso(node)) != NULL) while ((img = ventoy_get_min_iso(node)) != NULL)
{ {
g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
"menuentry \"%-10s %s\" --id=\"VID_%d\" {\n" "menuentry \"%-10s %s%s\" --id=\"VID_%d\" {\n"
" common_menuentry \n" " %s_%s \n"
"}\n", "}\n",
grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), img->name, img->id); grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
img->unsupport ? "[unsupported] " : "",
img->alias ? img->alias : img->name, img->id,
(img->type == img_type_iso) ? "iso" : "wim",
img->unsupport ? "unsupport_menuentry" : "common_menuentry");
} }
if (node != &g_img_iterator_head) if (node != &g_img_iterator_head)
{ {
g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, "}\n"); vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n");
} }
node->done = 1; node->done = 1;
@@ -943,6 +1072,7 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int len;
grub_fs_t fs; grub_fs_t fs;
grub_device_t dev = NULL; grub_device_t dev = NULL;
img_info *cur = NULL; img_info *cur = NULL;
@@ -992,14 +1122,37 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max)
{ {
debug("unsupported fs:<%s>\n", fs->name); debug("unsupported fs:<%s>\n", fs->name);
ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system");
goto fail; goto fail;
} }
strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE");
if (strdata && strdata[0] == '1')
{
g_default_menu_mode = 1;
}
grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head));
grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]);
strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
if (strdata && strdata[0] == '/')
{
len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata);
if (g_img_iterator_head.dir[len - 1] != '/')
{
g_img_iterator_head.dir[len++] = '/';
}
g_img_iterator_head.dirlen = len;
}
else
{
g_img_iterator_head.dirlen = 1; g_img_iterator_head.dirlen = 1;
g_img_iterator_head.tail = &tail;
grub_strcpy(g_img_iterator_head.dir, "/"); grub_strcpy(g_img_iterator_head.dir, "/");
}
g_img_iterator_head.tail = &tail;
for (node = &g_img_iterator_head; node; node = node->next) for (node = &g_img_iterator_head; node; node = node->next)
{ {
@@ -1032,13 +1185,24 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
} }
} }
if (g_default_menu_mode == 1)
{
vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
"menuentry \"%s [Return to TreeView]\" VTOY_RET {\n "
" echo 'return ...' \n"
"}\n", "<--");
}
for (cur = g_ventoy_img_list; cur; cur = cur->next) for (cur = g_ventoy_img_list; cur; cur = cur->next)
{ {
g_list_script_pos += grub_snprintf(g_list_script_buf + g_list_script_pos, VTOY_MAX_SCRIPT_BUF - g_list_script_pos, vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
"menuentry \"%s\" --id=\"VID_%d\" {\n" "menuentry \"%s%s\" --id=\"VID_%d\" {\n"
" common_menuentry \n" " %s_%s \n"
"}\n", "}\n",
cur->name, cur->id); cur->unsupport ? "[unsupported] " : "",
cur->alias ? cur->alias : cur->name, cur->id,
(cur->type == img_type_iso) ? "iso" : "wim",
cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
} }
g_list_script_buf[g_list_script_pos] = 0; g_list_script_buf[g_list_script_pos] = 0;
@@ -1256,6 +1420,7 @@ int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector)
void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
{ {
char *pos; char *pos;
const char *fs = NULL;
grub_uint32_t i; grub_uint32_t i;
grub_uint8_t chksum = 0; grub_uint8_t chksum = 0;
grub_disk_t disk; grub_disk_t disk;
@@ -1282,6 +1447,14 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
param->vtoy_reserved[0] = g_ventoy_break_level; param->vtoy_reserved[0] = g_ventoy_break_level;
param->vtoy_reserved[1] = g_ventoy_debug_level; param->vtoy_reserved[1] = g_ventoy_debug_level;
param->vtoy_reserved[2] = g_ventoy_chain_type;
fs = ventoy_get_env("ventoy_fs_probe");
if (fs && grub_strcmp(fs, "udf") == 0)
{
param->vtoy_reserved[3] = 1;
}
/* calculate checksum */ /* calculate checksum */
for (i = 0; i < sizeof(ventoy_os_param); i++) for (i = 0; i < sizeof(ventoy_os_param); i++)
{ {
@@ -1311,9 +1484,9 @@ int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist,
total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; total += chunk->disk_end_sector + 1 - chunk->disk_start_sector;
} }
if (total != (file->size / 512)) if (total != ((file->size + 511) / 512))
{ {
debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)(file->size / 512)); debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)((file->size + 511) / 512));
return 1; return 1;
} }
@@ -1417,6 +1590,123 @@ static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, ch
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
int pos = 0;
char *buf = NULL;
char configfile[128];
install_template *node = NULL;
(void)ctxt;
(void)argc;
(void)args;
debug("select auto installation %d\n", argc);
if (argc < 1)
{
return 0;
}
node = ventoy_plugin_find_install_template(args[0]);
if (!node)
{
debug("Install template not found for %s\n", args[0]);
return 0;
}
buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
if (!buf)
{
return 0;
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n"
" echo %s\n}\n", "123");
for (i = 0; i < node->templatenum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
" echo 123\n}\n",
node->templatepath[i].path);
}
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
grub_script_execute_sourcecode(configfile);
g_ventoy_menu_esc = 0;
g_ventoy_suppress_esc = 0;
grub_free(buf);
node->cursel = g_ventoy_last_entry - 1;
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
int pos = 0;
char *buf = NULL;
char configfile[128];
persistence_config *node;
(void)ctxt;
(void)argc;
(void)args;
debug("select persistece %d\n", argc);
if (argc < 1)
{
return 0;
}
node = ventoy_plugin_find_persistent(args[0]);
if (!node)
{
debug("Persistence image not found for %s\n", args[0]);
return 0;
}
buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
if (!buf)
{
return 0;
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n"
" echo %s\n}\n", "123");
for (i = 0; i < node->backendnum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
" echo 123\n}\n",
node->backendpath[i].path);
}
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
grub_script_execute_sourcecode(configfile);
g_ventoy_menu_esc = 0;
g_ventoy_suppress_esc = 0;
grub_free(buf);
node->cursel = g_ventoy_last_entry - 1;
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_uint32_t i; grub_uint32_t i;
@@ -1605,12 +1895,51 @@ static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, cha
return 0; return 0;
} }
static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args)
{
img_info *cur = g_ventoy_img_list;
(void)ctxt;
(void)argc;
(void)args;
while (cur)
{
grub_printf("path:<%s>\n", cur->path);
grub_printf("name:<%s>\n\n", cur->name);
cur = cur->next;
}
return 0;
}
static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
(void)args; (void)args;
{
grub_file_t file;
char *buf;
char name[128];
file = grub_file_open("(hd0,1)/ventoy/ventoy.disk.img.xz", GRUB_FILE_TYPE_NONE);
if (file)
{
grub_printf("Open File OK (size:%llu)\n", (ulonglong)file->size);
buf = grub_malloc(file->size);
grub_file_read(file, buf, file->size);
grub_file_close(file);
grub_snprintf(name, sizeof(name), "mem:0x%llx:size:%llu", (ulonglong)(ulong)buf, (ulonglong)file->size);
grub_printf("<%s>\n", name);
}
}
ventoy_plugin_dump_auto_install(); ventoy_plugin_dump_auto_install();
return 0; return 0;
@@ -1713,6 +2042,31 @@ static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc,
return 0; return 0;
} }
static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args)
{
grub_file_t file;
(void)ctxt;
if (argc != 1)
{
return 1;
}
g_ventoy_case_insensitive = 1;
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
g_ventoy_case_insensitive = 0;
grub_errno = 0;
if (file)
{
grub_file_close(file);
return 0;
}
return 1;
}
static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int id = 0; int id = 0;
@@ -1783,6 +2137,30 @@ static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int a
return 0; return 0;
} }
grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...)
{
grub_uint64_t size = 0;
grub_file_t file;
va_list ap;
char fullpath[256] = {0};
va_start (ap, fmt);
grub_vsnprintf(fullpath, 255, fmt, ap);
va_end (ap);
file = grub_file_open(fullpath, VENTOY_FILE_TYPE);
if (!file)
{
debug("grub_file_open failed <%s>\n", fullpath);
grub_errno = 0;
return 0;
}
size = file->size;
grub_file_close(file);
return size;
}
grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...)
{ {
va_list ap; va_list ap;
@@ -1836,6 +2214,8 @@ static int ventoy_env_init(void)
grub_env_set("vtdebug_flag", ""); grub_env_set("vtdebug_flag", "");
grub_env_export("vtdebug_flag"); grub_env_export("vtdebug_flag");
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
@@ -1867,14 +2247,19 @@ static cmd_para ventoy_cmds[] =
{ "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL },
{ "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL },
{ "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL },
{ "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL },
{ "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL },
{ "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL },
{ "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL },
{ "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL },
{ "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL },
{ "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL },
{ "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL },
{ "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
{ "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
{ "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL },
{ "vt_load_iso_to_mem", ventoy_cmd_load_iso_to_mem, 0, NULL, "", "", NULL }, { "vt_load_iso_to_mem", ventoy_cmd_load_iso_to_mem, 0, NULL, "", "", NULL },
@@ -1888,17 +2273,25 @@ static cmd_para ventoy_cmds[] =
{ "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL },
{ "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL },
{ "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL },
{ "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL },
{ "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL },
{ "vt_windows_locate_wim", ventoy_cmd_wimdows_locate_wim, 0, NULL, "", "", NULL },
{ "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL },
{ "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL },
{ "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL },
{ "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL },
{ "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL },
{ "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL },
{ "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL },
{ "vt_relocator_chaindata", ventoy_cmd_relocator_chaindata, 0, NULL, "", "", NULL }, { "vt_relocator_chaindata", ventoy_cmd_relocator_chaindata, 0, NULL, "", "", NULL },
{ "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL },
{ "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL },
{ "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL },
{ "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL },
}; };

View File

@@ -23,7 +23,10 @@
#define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024) #define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024)
#define VTOY_FILT_MIN_FILE_SIZE 32768
#define VTOY_SIZE_1GB 1073741824 #define VTOY_SIZE_1GB 1073741824
#define VTOY_SIZE_512KB (512 * 1024)
#define JSON_SUCCESS 0 #define JSON_SUCCESS 0
#define JSON_FAILED 1 #define JSON_FAILED 1
@@ -62,6 +65,7 @@ typedef struct cmd_para
grub_extcmd_t cmd; grub_extcmd_t cmd;
}cmd_para; }cmd_para;
#define ventoy_align_2k(value) ((value + 2047) / 2048 * 2048)
#define ventoy_align(value, align) (((value) + ((align) - 1)) & (~((align) - 1))) #define ventoy_align(value, align) (((value) + ((align) - 1)) & (~((align) - 1)))
#pragma pack(1) #pragma pack(1)
@@ -87,6 +91,7 @@ typedef struct cpio_newc_header
#define cmd_raw_name ctxt->extcmd->cmd->name #define cmd_raw_name ctxt->extcmd->cmd->name
#define check_free(p, func) if (p) { func(p); p = NULL; } #define check_free(p, func) if (p) { func(p); p = NULL; }
#define grub_check_free(p) if (p) { grub_free(p); p = NULL; }
typedef int (*grub_char_check_func)(int c); 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)
@@ -120,13 +125,21 @@ typedef struct ventoy_udf_override
#pragma pack() #pragma pack()
#define img_type_iso 0
#define img_type_wim 1
typedef struct img_info typedef struct img_info
{ {
char path[512]; char path[512];
char name[256]; char name[256];
const char *alias;
int id; int id;
int type;
grub_uint64_t size; grub_uint64_t size;
int select; int select;
int unsupport;
void *parent; void *parent;
@@ -186,12 +199,15 @@ extern grub_uint8_t *g_ventoy_runtime_buf;
extern ventoy_guid g_ventoy_guid; extern ventoy_guid g_ventoy_guid;
extern ventoy_img_chunk_list g_img_chunk_list; extern ventoy_img_chunk_list g_img_chunk_list;
extern ventoy_img_chunk_list g_wimiso_chunk_list;
extern char *g_wimiso_path;
extern int g_ventoy_debug; extern int g_ventoy_debug;
void ventoy_debug(const char *fmt, ...); void ventoy_debug(const char *fmt, ...);
#define debug(fmt, ...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, __VA_ARGS__) #define debug(fmt, ...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, __VA_ARGS__)
#define vtoy_ssprintf(buf, pos, fmt, ...) \
pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, __VA_ARGS__)
#define FLAG_HEADER_RESERVED 0x00000001 #define FLAG_HEADER_RESERVED 0x00000001
#define FLAG_HEADER_COMPRESSION 0x00000002 #define FLAG_HEADER_COMPRESSION 0x00000002
@@ -350,6 +366,19 @@ typedef struct wim_tail
grub_uint32_t new_lookup_align_len; grub_uint32_t new_lookup_align_len;
}wim_tail; }wim_tail;
typedef struct wim_patch
{
int pathlen;
char path[256];
wim_hash old_hash;
wim_tail wim_data;
wim_lookup_entry *replace_look;
int valid;
struct wim_patch *next;
}wim_patch;
typedef enum _JSON_TYPE typedef enum _JSON_TYPE
@@ -399,11 +428,13 @@ typedef struct _JSON_PARSE
} }
typedef int (*ventoy_plugin_entry_pf)(VTOY_JSON *json, const char *isodisk); typedef int (*ventoy_plugin_entry_pf)(VTOY_JSON *json, const char *isodisk);
typedef int (*ventoy_plugin_check_pf)(VTOY_JSON *json, const char *isodisk);
typedef struct plugin_entry typedef struct plugin_entry
{ {
const char *key; const char *key;
ventoy_plugin_entry_pf entryfunc; ventoy_plugin_entry_pf entryfunc;
ventoy_plugin_check_pf checkfunc;
}plugin_entry; }plugin_entry;
@@ -422,12 +453,14 @@ grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, c
grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args);
int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name); int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name);
grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...);
grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...);
int ventoy_is_file_exist(const char *fmt, ...); int ventoy_is_file_exist(const char *fmt, ...);
int ventoy_fill_data(grub_uint32_t buflen, char *buffer); int ventoy_fill_data(grub_uint32_t buflen, char *buffer);
grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
VTOY_JSON *vtoy_json_find_item VTOY_JSON *vtoy_json_find_item
( (
@@ -552,37 +585,70 @@ typedef struct ventoy_mbr_head
}ventoy_mbr_head; }ventoy_mbr_head;
#pragma pack() #pragma pack()
typedef struct file_fullpath
{
char path[256];
}file_fullpath;
typedef struct install_template typedef struct install_template
{ {
int pathlen;
char isopath[256]; char isopath[256];
char templatepath[256];
int cursel;
int templatenum;
file_fullpath *templatepath;
struct install_template *next; struct install_template *next;
}install_template; }install_template;
typedef struct persistence_config typedef struct persistence_config
{ {
int pathlen;
char isopath[256]; char isopath[256];
char filepath[256];
int cursel;
int backendnum;
file_fullpath *backendpath;
struct persistence_config *next; struct persistence_config *next;
}persistence_config; }persistence_config;
typedef struct menu_alias
{
int pathlen;
char isopath[256];
char alias[256];
struct menu_alias *next;
}menu_alias;
extern int g_ventoy_menu_esc;
extern int g_ventoy_suppress_esc;
extern int g_ventoy_last_entry; extern int g_ventoy_last_entry;
extern int g_ventoy_memdisk_mode; extern int g_ventoy_memdisk_mode;
extern int g_ventoy_iso_raw; 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 grub_uint8_t g_ventoy_chain_type;
int ventoy_cmp_img(img_info *img1, img_info *img2); int ventoy_cmp_img(img_info *img1, img_info *img2);
void ventoy_swap_img(img_info *img1, img_info *img2); void ventoy_swap_img(img_info *img1, img_info *img2);
char * ventoy_plugin_get_install_template(const char *isopath); char * ventoy_plugin_get_cur_install_template(const char *isopath);
install_template * ventoy_plugin_find_install_template(const char *isopath);
persistence_config * ventoy_plugin_find_persistent(const char *isopath);
void ventoy_plugin_dump_auto_install(void); void ventoy_plugin_dump_auto_install(void);
int ventoy_fill_windows_rtdata(void *buf, char *isopath); int ventoy_fill_windows_rtdata(void *buf, char *isopath);
int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list); int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list);
const char * ventoy_plugin_get_menu_alias(const char *isopath);
int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); int ventoy_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);
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
#endif /* __VENTOY_DEF_H__ */ #endif /* __VENTOY_DEF_H__ */

View File

@@ -42,6 +42,11 @@ static void json_debug(const char *fmt, ...)
{ {
va_list args; va_list args;
if (g_ventoy_debug == 0)
{
return;
}
va_start (args, fmt); va_start (args, fmt);
grub_vprintf (fmt, args); grub_vprintf (fmt, args);
va_end (args); va_end (args);

View File

@@ -686,6 +686,8 @@ static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override) static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override)
{ {
initrd_info *node; initrd_info *node;
grub_uint32_t mod;
grub_uint32_t newlen;
grub_uint64_t sector; grub_uint64_t sector;
ventoy_override_chunk *cur; ventoy_override_chunk *cur;
@@ -699,13 +701,20 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
continue; continue;
} }
newlen = (grub_uint32_t)(node->size + g_ventoy_cpio_size);
mod = newlen % 4;
if (mod > 0)
{
newlen += 4 - mod;
}
if (node->iso_type == 0) if (node->iso_type == 0)
{ {
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)node->override_data; ventoy_iso9660_override *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;
dirent->size = (grub_uint32_t)(node->size + g_ventoy_cpio_size); dirent->size = newlen;
dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
dirent->size_be = grub_swap_bytes32(dirent->size); dirent->size_be = grub_swap_bytes32(dirent->size);
@@ -716,7 +725,7 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove
ventoy_udf_override *udf = (ventoy_udf_override *)node->override_data; ventoy_udf_override *udf = (ventoy_udf_override *)node->override_data;
node->override_length = sizeof(ventoy_udf_override); node->override_length = sizeof(ventoy_udf_override);
udf->length = (grub_uint32_t)(node->size + g_ventoy_cpio_size); udf->length = newlen;
udf->position = (grub_uint32_t)sector - node->udf_start_block; udf->position = (grub_uint32_t)sector - node->udf_start_block;
sector += (udf->length + 2047) / 2048; sector += (udf->length + 2047) / 2048;
@@ -832,6 +841,50 @@ static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt)
} }
grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args)
{
int index = 0;
char buf[32];
initrd_info *node = NULL;
(void)ctxt;
(void)argc;
(void)args;
if (argc != 1)
{
return 1;
}
if (g_initrd_img_count == 1)
{
ventoy_set_env(args[0], "0");
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
for (node = g_initrd_img_list; node; node = node->next)
{
if (node->size <= 0)
{
continue;
}
if (grub_strstr(node->name, "ucode") || grub_strstr(node->name, "-firmware"))
{
index++;
continue;
}
grub_snprintf(buf, sizeof(buf), "%d", index);
ventoy_set_env(args[0], buf);
break;
}
debug("main initrd index:%d\n", index);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args) grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args)
{ {
int sizefilt = 0; int sizefilt = 0;
@@ -896,14 +949,14 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
g_ventoy_cpio_size = 0; g_ventoy_cpio_size = 0;
} }
rc = ventoy_plugin_get_persistent_chunklist(args[1], &chunk_list); rc = ventoy_plugin_get_persistent_chunklist(args[1], -1, &chunk_list);
if (rc == 0 && chunk_list.cur_chunk > 0 && chunk_list.chunk) if (rc == 0 && chunk_list.cur_chunk > 0 && chunk_list.chunk)
{ {
persistent_size = chunk_list.cur_chunk * sizeof(ventoy_img_chunk); persistent_size = chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
persistent_buf = (char *)(chunk_list.chunk); persistent_buf = (char *)(chunk_list.chunk);
} }
template_file = ventoy_plugin_get_install_template(args[1]); template_file = ventoy_plugin_get_cur_install_template(args[1]);
if (template_file) if (template_file)
{ {
debug("auto install template: <%s>\n", template_file); debug("auto install template: <%s>\n", template_file);
@@ -925,6 +978,10 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg
debug("Failed to open install script %s%s\n", args[2], template_file); debug("Failed to open install script %s%s\n", args[2], template_file);
} }
} }
else
{
debug("auto install script skipped or not configed %s\n", args[1]);
}
g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size); g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size);
if (NULL == g_ventoy_cpio_buf) if (NULL == g_ventoy_cpio_buf)
@@ -1087,6 +1144,7 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
grub_memset(chain, 0, sizeof(ventoy_chain_head)); grub_memset(chain, 0, sizeof(ventoy_chain_head));
/* part 1: os parameter */ /* part 1: os parameter */
g_ventoy_chain_type = 0;
ventoy_fill_os_param(file, &(chain->os_param)); ventoy_fill_os_param(file, &(chain->os_param));
/* part 2: chain head */ /* part 2: chain head */

View File

@@ -41,6 +41,46 @@ GRUB_MOD_LICENSE ("GPLv3+");
static char g_iso_disk_name[128]; static char g_iso_disk_name[128];
static install_template *g_install_template_head = NULL; static install_template *g_install_template_head = NULL;
static persistence_config *g_persistence_head = NULL; static persistence_config *g_persistence_head = NULL;
static menu_alias *g_menu_alias_head = NULL;
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
{
int rc = 0;
VTOY_JSON *pNode = NULL;
VTOY_JSON *pChild = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY)
{
grub_printf("Not array type %d\n", json->enDataType);
return 1;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType == JSON_TYPE_OBJECT)
{
pChild = pNode->pstChild;
if (pChild->enDataType == JSON_TYPE_STRING)
{
grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
}
else
{
grub_printf("%s is NOT string type\n", pChild->pcName);
rc = 1;
}
}
else
{
grub_printf("%s is not an object\n", pNode->pcName);
rc = 1;
}
}
return rc;
}
static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
{ {
@@ -70,6 +110,64 @@ static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
return 0; return 0;
} }
static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
{
int exist = 0;
const char *value;
value = vtoy_json_get_string_ex(json->pstChild, "file");
if (value)
{
grub_printf("file: %s\n", value);
if (value[0] == '/')
{
exist = ventoy_is_file_exist("%s%s", isodisk, value);
}
else
{
exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
}
if (exist == 0)
{
grub_printf("Theme file %s does NOT exist\n", value);
return 1;
}
}
value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
if (value)
{
grub_printf("gfxmode: %s\n", value);
}
value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
if (value)
{
grub_printf("display_mode: %s\n", value);
}
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
if (value)
{
grub_printf("ventoy_left: %s\n", value);
}
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
if (value)
{
grub_printf("ventoy_top: %s\n", value);
}
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
if (value)
{
grub_printf("ventoy_color: %s\n", value);
}
return 0;
}
static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
{ {
const char *value; const char *value;
@@ -104,6 +202,13 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
grub_env_set("vtoy_gfxmode", value); grub_env_set("vtoy_gfxmode", value);
} }
value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
if (value)
{
debug("display_mode %s\n", value);
grub_env_set("vtoy_display_mode", value);
}
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
if (value) if (value)
{ {
@@ -125,16 +230,224 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
return 0; return 0;
} }
static int ventoy_plugin_check_path(const char *path, const char *file)
{
if (file[0] != '/')
{
grub_printf("%s is NOT begin with '/' \n", file);
return 1;
}
if (grub_strchr(file, '\\'))
{
grub_printf("%s contains invalid '\\' \n", file);
return 1;
}
if (grub_strstr(file, "//"))
{
grub_printf("%s contains invalid double slash\n", file);
return 1;
}
if (grub_strstr(file, "../"))
{
grub_printf("%s contains invalid '../' \n", file);
return 1;
}
if (!ventoy_is_file_exist("%s%s", path, file))
{
grub_printf("%s%s does NOT exist\n", path, file);
return 1;
}
return 0;
}
static int ventoy_plugin_check_fullpath
(
VTOY_JSON *json,
const char *isodisk,
const char *key
)
{
int rc = 0;
int ret = 0;
VTOY_JSON *node = json;
VTOY_JSON *child = NULL;
while (node)
{
if (0 == grub_strcmp(key, node->pcName))
{
break;
}
node = node->pstNext;
}
if (!node)
{
return 1;
}
if (JSON_TYPE_STRING == node->enDataType)
{
ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
}
else if (JSON_TYPE_ARRAY == node->enDataType)
{
for (child = node->pstChild; child; child = child->pstNext)
{
if (JSON_TYPE_STRING != child->enDataType)
{
grub_printf("Non string json type\n");
}
else
{
rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
ret += rc;
}
}
}
return ret;
}
static int ventoy_plugin_parse_fullpath
(
VTOY_JSON *json,
const char *isodisk,
const char *key,
file_fullpath **fullpath,
int *pathnum
)
{
int rc = 1;
int count = 0;
VTOY_JSON *node = json;
VTOY_JSON *child = NULL;
file_fullpath *path = NULL;
while (node)
{
if (0 == grub_strcmp(key, node->pcName))
{
break;
}
node = node->pstNext;
}
if (!node)
{
return 1;
}
if (JSON_TYPE_STRING == node->enDataType)
{
debug("%s is string type data\n", node->pcName);
if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal)))
{
debug("%s%s file not found\n", isodisk, node->unData.pcStrVal);
return 1;
}
path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath));
if (path)
{
grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal);
*fullpath = path;
*pathnum = 1;
rc = 0;
}
}
else if (JSON_TYPE_ARRAY == node->enDataType)
{
for (child = node->pstChild; child; child = child->pstNext)
{
if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/'))
{
debug("Invalid data type:%d\n", child->enDataType);
return 1;
}
count++;
}
debug("%s is array type data, count=%d\n", node->pcName, count);
path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count);
if (path)
{
*fullpath = path;
for (count = 0, child = node->pstChild; child; child = child->pstNext)
{
if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal))
{
grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal);
path++;
count++;
}
}
*pathnum = count;
rc = 0;
}
}
return rc;
}
static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk)
{
const char *iso = NULL;
VTOY_JSON *pNode = NULL;
if (json->enDataType != JSON_TYPE_ARRAY)
{
grub_printf("Not array type %d\n", json->enDataType);
return 1;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType != JSON_TYPE_OBJECT)
{
grub_printf("NOT object type\n");
}
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
if (iso)
{
if (0 == ventoy_plugin_check_path(isodisk, iso))
{
grub_printf("image: %s [OK]\n", iso);
ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template");
}
else
{
grub_printf("image: %s [FAIL]\n", iso);
}
}
else
{
grub_printf("image not found\n");
}
}
return 0;
}
static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk)
{ {
int pathnum = 0;
const char *iso = NULL; const char *iso = NULL;
const char *script = NULL;
VTOY_JSON *pNode = NULL; VTOY_JSON *pNode = NULL;
install_template *node = NULL; install_template *node = NULL;
install_template *next = NULL; install_template *next = NULL;
file_fullpath *templatepath = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY) if (json->enDataType != JSON_TYPE_ARRAY)
{ {
@@ -147,6 +460,7 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
for (node = g_install_template_head; node; node = next) for (node = g_install_template_head; node; node = next)
{ {
next = node->next; next = node->next;
grub_check_free(node->templatepath);
grub_free(node); grub_free(node);
} }
@@ -158,14 +472,14 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
if (iso && iso[0] == '/') if (iso && iso[0] == '/')
{ {
script = vtoy_json_get_string_ex(pNode->pstChild, "template"); if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum))
if (script && script[0] == '/')
{ {
node = grub_zalloc(sizeof(install_template)); node = grub_zalloc(sizeof(install_template));
if (node) if (node)
{ {
grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
grub_snprintf(node->templatepath, sizeof(node->templatepath), "%s", script); node->templatepath = templatepath;
node->templatenum = pathnum;
if (g_install_template_head) if (g_install_template_head)
{ {
@@ -181,14 +495,54 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
return 0; return 0;
} }
static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
{
const char *iso = NULL;
VTOY_JSON *pNode = NULL;
if (json->enDataType != JSON_TYPE_ARRAY)
{
grub_printf("Not array type %d\n", json->enDataType);
return 1;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
if (pNode->enDataType != JSON_TYPE_OBJECT)
{
grub_printf("NOT object type\n");
}
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
if (iso)
{
if (0 == ventoy_plugin_check_path(isodisk, iso))
{
grub_printf("image: %s [OK]\n", iso);
ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend");
}
else
{
grub_printf("image: %s [FAIL]\n", iso);
}
}
else
{
grub_printf("image not found\n");
}
}
return 0;
}
static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
{ {
int pathnum = 0;
const char *iso = NULL; const char *iso = NULL;
const char *persist = NULL;
VTOY_JSON *pNode = NULL; VTOY_JSON *pNode = NULL;
persistence_config *node = NULL; persistence_config *node = NULL;
persistence_config *next = NULL; persistence_config *next = NULL;
file_fullpath *backendpath = NULL;
(void)isodisk; (void)isodisk;
@@ -203,6 +557,7 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
for (node = g_persistence_head; node; node = next) for (node = g_persistence_head; node; node = next)
{ {
next = node->next; next = node->next;
grub_check_free(node->backendpath);
grub_free(node); grub_free(node);
} }
@@ -214,14 +569,14 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
if (iso && iso[0] == '/') if (iso && iso[0] == '/')
{ {
persist = vtoy_json_get_string_ex(pNode->pstChild, "backend"); if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum))
if (persist && persist[0] == '/')
{ {
node = grub_zalloc(sizeof(persistence_config)); node = grub_zalloc(sizeof(persistence_config));
if (node) if (node)
{ {
grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
grub_snprintf(node->filepath, sizeof(node->filepath), "%s", persist); node->backendpath = backendpath;
node->backendnum = pathnum;
if (g_persistence_head) if (g_persistence_head)
{ {
@@ -237,13 +592,93 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
return 0; return 0;
} }
static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
{
const char *iso = NULL;
const char *alias = NULL;
VTOY_JSON *pNode = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY)
{
grub_printf("Not array %d\n", json->enDataType);
return 1;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
if (iso && iso[0] == '/' && alias)
{
grub_printf("image: <%s>\n", iso);
grub_printf("alias: <%s>\n\n", alias);
}
}
return 0;
}
static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk)
{
const char *iso = NULL;
const char *alias = NULL;
VTOY_JSON *pNode = NULL;
menu_alias *node = NULL;
menu_alias *next = NULL;
(void)isodisk;
if (json->enDataType != JSON_TYPE_ARRAY)
{
debug("Not array %d\n", json->enDataType);
return 0;
}
if (g_menu_alias_head)
{
for (node = g_menu_alias_head; node; node = next)
{
next = node->next;
grub_free(node);
}
g_menu_alias_head = NULL;
}
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
{
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
if (iso && iso[0] == '/' && alias)
{
node = grub_zalloc(sizeof(menu_alias));
if (node)
{
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
grub_snprintf(node->alias, sizeof(node->alias), "%s", alias);
if (g_menu_alias_head)
{
node->next = g_menu_alias_head;
}
g_menu_alias_head = node;
}
}
}
return 0;
}
static plugin_entry g_plugin_entries[] = static plugin_entry g_plugin_entries[] =
{ {
{ "control", ventoy_plugin_control_entry }, { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
{ "theme", ventoy_plugin_theme_entry }, { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
{ "auto_install", ventoy_plugin_auto_install_entry }, { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
{ "persistence", ventoy_plugin_persistence_entry }, { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check },
{ "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
}; };
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
@@ -325,15 +760,18 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
VENTOY_CMD_RETURN(GRUB_ERR_NONE); VENTOY_CMD_RETURN(GRUB_ERR_NONE);
} }
void ventoy_plugin_dump_auto_install(void) void ventoy_plugin_dump_auto_install(void)
{ {
int i;
install_template *node = NULL; install_template *node = NULL;
for (node = g_install_template_head; node; node = node->next) for (node = g_install_template_head; node; node = node->next)
{ {
grub_printf("IMAGE:<%s>\n", node->isopath); grub_printf("\nIMAGE:<%s>\n", node->isopath);
grub_printf("SCRIPT:<%s>\n\n", node->templatepath); for (i = 0; i < node->templatenum; i++)
{
grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path);
}
} }
return; return;
@@ -342,69 +780,110 @@ void ventoy_plugin_dump_auto_install(void)
void ventoy_plugin_dump_persistence(void) void ventoy_plugin_dump_persistence(void)
{ {
int rc; int rc;
int i = 0;
persistence_config *node = NULL; persistence_config *node = NULL;
ventoy_img_chunk_list chunk_list; ventoy_img_chunk_list chunk_list;
for (node = g_persistence_head; node; node = node->next) for (node = g_persistence_head; node; node = node->next)
{ {
grub_printf("IMAGE:<%s>\n", node->isopath); grub_printf("\nIMAGE:<%s>\n", node->isopath);
grub_printf("PERSIST:<%s>", node->filepath);
rc = ventoy_plugin_get_persistent_chunklist(node->isopath, &chunk_list); for (i = 0; i < node->backendnum; i++)
{
grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path);
rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list);
if (rc == 0) if (rc == 0)
{ {
grub_printf(" [ SUCCESS ]\n\n"); grub_printf(" [ SUCCESS ]\n");
grub_free(chunk_list.chunk); grub_free(chunk_list.chunk);
} }
else else
{ {
grub_printf(" [ FAILED ]\n\n"); grub_printf(" [ FAILED ]\n");
}
} }
} }
return; return;
} }
install_template * ventoy_plugin_find_install_template(const char *isopath)
char * ventoy_plugin_get_install_template(const char *isopath)
{ {
install_template *node = NULL; install_template *node = NULL;
int 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 (grub_strcmp(node->isopath, isopath) == 0) if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
{ {
return node->templatepath; return node;
} }
} }
return NULL; return NULL;
} }
int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list) char * ventoy_plugin_get_cur_install_template(const char *isopath)
{
install_template *node = NULL;
node = ventoy_plugin_find_install_template(isopath);
if ((!node) || (!node->templatepath))
{
return NULL;
}
if (node->cursel < 0 || node->cursel >= node->templatenum)
{
return NULL;
}
return node->templatepath[node->cursel].path;
}
persistence_config * ventoy_plugin_find_persistent(const char *isopath)
{
persistence_config *node = NULL;
int len = (int)grub_strlen(isopath);
for (node = g_persistence_head; node; node = node->next)
{
if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0))
{
return node;
}
}
return NULL;
}
int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list)
{ {
int rc = 1; int rc = 1;
grub_uint64_t start = 0; grub_uint64_t start = 0;
grub_file_t file = NULL; grub_file_t file = NULL;
persistence_config *node = NULL; persistence_config *node = NULL;
for (node = g_persistence_head; node; node = node->next) node = ventoy_plugin_find_persistent(isopath);
if ((!node) || (!node->backendpath))
{ {
if (grub_strcmp(node->isopath, isopath) == 0) return 1;
{
break;
}
} }
if (NULL == node) if (index < 0)
{ {
goto end; index = node->cursel;
} }
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->filepath); if (index < 0 || index >= node->backendnum)
{
return 1;
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path);
if (!file) if (!file)
{ {
debug("Failed to open file %s%s\n", g_iso_disk_name, node->filepath); debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path);
goto end; goto end;
} }
@@ -437,3 +916,100 @@ end:
return rc; return rc;
} }
const char * ventoy_plugin_get_menu_alias(const char *isopath)
{
menu_alias *node = NULL;
int len = (int)grub_strlen(isopath);
for (node = g_menu_alias_head; node; node = node->next)
{
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
{
return node->alias;
}
}
return NULL;
}
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
int ret = 0;
char *buf = NULL;
grub_file_t file;
VTOY_JSON *node = NULL;
VTOY_JSON *json = NULL;
(void)ctxt;
if (argc != 3)
{
return 0;
}
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]);
if (!file)
{
grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
goto end;
}
buf = grub_malloc(file->size + 1);
if (!buf)
{
grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
goto end;
}
buf[file->size] = 0;
grub_file_read(file, buf, file->size);
json = vtoy_json_create();
if (!json)
{
grub_printf("Failed to create json\n");
goto end;
}
ret = vtoy_json_parse(json, buf);
if (ret)
{
grub_printf("Syntax error detected in ventoy.json, please check it.\n");
goto end;
}
for (node = json->pstChild; node; node = node->pstNext)
{
if (grub_strcmp(node->pcName, args[1]) == 0)
{
break;
}
}
if (!node)
{
grub_printf("%s is NOT found in ventoy.json\n", args[1]);
goto end;
}
for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
{
if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
{
if (g_plugin_entries[i].checkfunc)
{
ret = g_plugin_entries[i].checkfunc(node, args[2]);
}
break;
}
}
end:
check_free(file, grub_file_close);
check_free(json, vtoy_json_destroy);
grub_check_free(buf);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,243 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_FILE_HEADER
#define GRUB_FILE_HEADER 1
#include <grub/types.h>
#include <grub/err.h>
#include <grub/device.h>
#include <grub/fs.h>
#include <grub/disk.h>
enum grub_file_type
{
GRUB_FILE_TYPE_NONE = 0,
/* GRUB module to be loaded. */
GRUB_FILE_TYPE_GRUB_MODULE,
/* Loopback file to be represented as disk. */
GRUB_FILE_TYPE_LOOPBACK,
/* Linux kernel to be loaded. */
GRUB_FILE_TYPE_LINUX_KERNEL,
/* Linux initrd. */
GRUB_FILE_TYPE_LINUX_INITRD,
/* Multiboot kernel. */
GRUB_FILE_TYPE_MULTIBOOT_KERNEL,
/* Multiboot module. */
GRUB_FILE_TYPE_MULTIBOOT_MODULE,
/* Xen hypervisor - used on ARM only. */
GRUB_FILE_TYPE_XEN_HYPERVISOR,
/* Xen module - used on ARM only. */
GRUB_FILE_TYPE_XEN_MODULE,
GRUB_FILE_TYPE_BSD_KERNEL,
GRUB_FILE_TYPE_FREEBSD_ENV,
GRUB_FILE_TYPE_FREEBSD_MODULE,
GRUB_FILE_TYPE_FREEBSD_MODULE_ELF,
GRUB_FILE_TYPE_NETBSD_MODULE,
GRUB_FILE_TYPE_OPENBSD_RAMDISK,
GRUB_FILE_TYPE_XNU_INFO_PLIST,
GRUB_FILE_TYPE_XNU_MKEXT,
GRUB_FILE_TYPE_XNU_KEXT,
GRUB_FILE_TYPE_XNU_KERNEL,
GRUB_FILE_TYPE_XNU_RAMDISK,
GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE,
GRUB_FILE_XNU_DEVPROP,
GRUB_FILE_TYPE_PLAN9_KERNEL,
GRUB_FILE_TYPE_NTLDR,
GRUB_FILE_TYPE_TRUECRYPT,
GRUB_FILE_TYPE_FREEDOS,
GRUB_FILE_TYPE_PXECHAINLOADER,
GRUB_FILE_TYPE_PCCHAINLOADER,
GRUB_FILE_TYPE_COREBOOT_CHAINLOADER,
GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE,
/* File holding signature. */
GRUB_FILE_TYPE_SIGNATURE,
/* File holding public key to verify signature once. */
GRUB_FILE_TYPE_PUBLIC_KEY,
/* File holding public key to add to trused keys. */
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST,
/* File of which we intend to print a blocklist to the user. */
GRUB_FILE_TYPE_PRINT_BLOCKLIST,
/* File we intend to use for test loading or testing speed. */
GRUB_FILE_TYPE_TESTLOAD,
/* File we open only to get its size. E.g. in ls output. */
GRUB_FILE_TYPE_GET_SIZE,
/* Font file. */
GRUB_FILE_TYPE_FONT,
/* File holding encryption key for encrypted ZFS. */
GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY,
/* File we open n grub-fstest. */
GRUB_FILE_TYPE_FSTEST,
/* File we open n grub-mount. */
GRUB_FILE_TYPE_MOUNT,
/* File which we attempt to identify the type of. */
GRUB_FILE_TYPE_FILE_ID,
/* File holding ACPI table. */
GRUB_FILE_TYPE_ACPI_TABLE,
/* File holding Device Tree. */
GRUB_FILE_TYPE_DEVICE_TREE_IMAGE,
/* File we intend show to user. */
GRUB_FILE_TYPE_CAT,
GRUB_FILE_TYPE_HEXCAT,
/* One of pair of files we intend to compare. */
GRUB_FILE_TYPE_CMP,
/* List of hashes for hashsum. */
GRUB_FILE_TYPE_HASHLIST,
/* File hashed by hashsum. */
GRUB_FILE_TYPE_TO_HASH,
/* Keyboard layout. */
GRUB_FILE_TYPE_KEYBOARD_LAYOUT,
/* Picture file. */
GRUB_FILE_TYPE_PIXMAP,
/* *.lst shipped by GRUB. */
GRUB_FILE_TYPE_GRUB_MODULE_LIST,
/* config file. */
GRUB_FILE_TYPE_CONFIG,
GRUB_FILE_TYPE_THEME,
GRUB_FILE_TYPE_GETTEXT_CATALOG,
GRUB_FILE_TYPE_FS_SEARCH,
GRUB_FILE_TYPE_AUDIO,
GRUB_FILE_TYPE_VBE_DUMP,
GRUB_FILE_TYPE_LOADENV,
GRUB_FILE_TYPE_SAVEENV,
GRUB_FILE_TYPE_VERIFY_SIGNATURE,
GRUB_FILE_TYPE_MASK = 0xffff,
/* --skip-sig is specified. */
GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000,
GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000
};
/* File description. */
struct grub_file
{
/* File name. */
char *name;
/* The underlying device. */
grub_device_t device;
/* The underlying filesystem. */
grub_fs_t fs;
/* The current offset. */
grub_off_t offset;
grub_off_t progress_offset;
/* Progress info. */
grub_uint64_t last_progress_time;
grub_off_t last_progress_offset;
grub_uint64_t estimated_speed;
/* The file size. */
grub_off_t size;
/* If file is not easily seekable. Should be set by underlying layer. */
int not_easily_seekable;
/* Filesystem-specific data. */
void *data;
/* This is called when a sector is read. Used only for a disk device. */
grub_disk_read_hook_t read_hook;
/* Caller-specific data passed to the read hook. */
void *read_hook_data;
};
typedef struct grub_file *grub_file_t;
extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
/* Filters with lower ID are executed first. */
typedef enum grub_file_filter_id
{
GRUB_FILE_FILTER_VERIFY,
GRUB_FILE_FILTER_GZIO,
GRUB_FILE_FILTER_XZIO,
GRUB_FILE_FILTER_LZOPIO,
GRUB_FILE_FILTER_MAX,
GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO,
GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO,
} grub_file_filter_id_t;
typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type);
extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX];
static inline void
grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter)
{
grub_file_filters[id] = filter;
}
static inline void
grub_file_filter_unregister (grub_file_filter_id_t id)
{
grub_file_filters[id] = 0;
}
/* Get a device name from NAME. */
char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
int EXPORT_FUNC(ventoy_check_file_exist) (const char * fmt, ...);
grub_file_t EXPORT_FUNC(grub_file_open) (const char *name, enum grub_file_type type);
grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
grub_size_t len);
grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
/* Return value of grub_file_size() in case file size is unknown. */
#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL
static inline grub_off_t
grub_file_size (const grub_file_t file)
{
return file->size;
}
static inline grub_off_t
grub_file_tell (const grub_file_t file)
{
return file->offset;
}
static inline int
grub_file_seekable (const grub_file_t file)
{
return !file->not_easily_seekable;
}
grub_file_t
grub_file_offset_open (grub_file_t parent, enum grub_file_type type,
grub_off_t start, grub_off_t size);
void
grub_file_offset_close (grub_file_t file);
#endif /* ! GRUB_FILE_HEADER */

View File

@@ -109,6 +109,8 @@ typedef struct ventoy_os_param
* *
* vtoy_reserved[0]: vtoy_break_level * vtoy_reserved[0]: vtoy_break_level
* vtoy_reserved[1]: vtoy_debug_level * vtoy_reserved[1]: vtoy_debug_level
* vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows
* vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf
* *
*/ */
grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy
@@ -227,6 +229,7 @@ typedef struct ventoy_grub_param
int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list);
int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list);
void grub_iso9660_set_nojoliet(int nojoliet);
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file); grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file);
grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file); grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file);
grub_uint64_t grub_udf_get_file_offset(grub_file_t file); grub_uint64_t grub_udf_get_file_offset(grub_file_t file);

View File

@@ -12,10 +12,10 @@ make install
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/ PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
net_modules_legacy="net tftp http" net_modules_legacy="net tftp http"
all_modules_legacy="date drivemap blocklist ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" all_modules_legacy="date drivemap blocklist ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu"
net_modules_uefi="efinet net tftp http" net_modules_uefi="efinet net tftp http"
all_modules_uefi="blocklist ventoy test ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu" all_modules_uefi="blocklist ventoy test search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu"
if [ "$1" = "uefi" ]; then if [ "$1" = "uefi" ]; then

View File

@@ -19,22 +19,24 @@
. /ventoy/hook/ventoy-hook-lib.sh . /ventoy/hook/ventoy-hook-lib.sh
if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then if is_ventoy_hook_finished; then
exit 0 exit 0
fi fi
ventoy_udev_disk_common_hook $* vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
# ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
# cheatcode for mageia
# if ! [ -e $VTOY_DM_PATH ]; then
# From mageia/soft/drakx/mdk-stage1 source code, we see that the stage1 binary will search blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/')
# /tmp/syslog file to determin whether there is a DAC960 cdrom in the system. mknod -m 0666 $VTOY_DM_PATH b $blkdev_num
# So we insert some string to /tmp/syslog file to cheat the stage1 program. fi
#
$BUSYBOX_PATH/mkdir -p /dev/rd
ventoy_copy_device_mapper "/dev/rd/ventoy"
echo 'ventoy cheatcode /dev/rd/ventoy: model' >> /tmp/syslog
# OK finish # OK finish
set_ventoy_hook_finish set_ventoy_hook_finish

View File

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

View File

@@ -22,6 +22,10 @@
if $GREP -q '^"$mount_handler"' /init; then if $GREP -q '^"$mount_handler"' /init; then
echo 'use mount_handler ...' >> $VTLOG echo 'use mount_handler ...' >> $VTLOG
$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
if [ -f /hooks/archiso ]; then
$SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/archiso
fi
else else
# some archlinux initramfs doesn't contain device-mapper udev rules file # some archlinux initramfs doesn't contain device-mapper udev rules file
ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir)

View File

@@ -0,0 +1,36 @@
#!/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 $* ############"
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})
if [ -b /dev/$vtDM ]; then
vtlog "ln -s /dev/$vtDM $1"
ln -s /dev/$vtDM "$1"
exit 0
else
vtlog "Device-mapper not found"
exit 1
fi

View File

@@ -19,4 +19,10 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
if $GREP -q find_and_mount_installer /init; then
echo "find_and_mount_installer" >> $VTLOG
$SED "/find_and_mount_installer *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init $SED "/find_and_mount_installer *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init
else
echo "find_installer" >> $VTLOG
$SED "/\$.*find_installer/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init
fi

View File

@@ -21,5 +21,11 @@
vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt)
vtdisk=$(get_ventoy_disk_name)
if [ "$vtdisk" = "unknown" ]; then
vtlog "... start inotifyd listen $vtHook ..." vtlog "... start inotifyd listen $vtHook ..."
$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- &
else
vtlog "... $vtdisk already exist ..."
$BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2"
fi

View File

@@ -19,13 +19,11 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
if [ -d /etc/udev/rules.d ]; 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
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"
else
if $GREP -q kaspersky /proc/version; then
$SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
else else
$SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
fi fi
fi

View File

@@ -0,0 +1,70 @@
#!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
ventoy_os_install_dmsetup_by_unsquashfs() {
vtlog "ventoy_os_install_dmsetup_by_unsquashfs $*"
vtKerVer=$(uname -r)
vtKoPo=$(ventoy_get_module_postfix)
vtlog "vtKerVer=$vtKerVer vtKoPo=$vtKoPo"
vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/iso_file_list
vtline=$(grep '[-][-] .*kernel.xzm ' $VTOY_PATH/iso_file_list)
sector=$(echo $vtline | awk '{print $(NF-1)}')
length=$(echo $vtline | awk '{print $NF}')
vtlog "vtline=$vtline sector=$sector length=$length"
vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $1 -s $sector -l $length -o $VTOY_PATH/kernel.xzm
mkdir -p $VTOY_PATH/sqfs
mount $VTOY_PATH/kernel.xzm $VTOY_PATH/sqfs
dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo"
if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then
vtlog "success $VTOY_PATH/sqfs${dmModPath}"
insmod $VTOY_PATH/sqfs${dmModPath}
else
vterr "failed $VTOY_PATH/sqfs${dmModPath}"
false
fi
umount $VTOY_PATH/sqfs
rm -f $VTOY_PATH/kernel.xzm
}
wait_for_usb_disk_ready
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
ventoy_os_install_dmsetup_by_unsquashfs $vtdiskname
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
PATH=$VTPATH_OLD

View File

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

View File

@@ -1,7 +1,29 @@
#!/ventoy/busybox/sh #!/ventoy/busybox/sh
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
ventoy_systemd_udevd_work_around #ventoy_systemd_udevd_work_around
#ventoy_add_udev_rule "$VTOY_PATH/hook/mageia/udev_disk_hook.sh %k noreplace"
ventoy_set_inotify_script mageia/ventoy-inotifyd-hook.sh
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/mageia/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/99-ventoy-inotifyd-start.sh
ventoy_add_udev_rule "$VTOY_PATH/hook/mageia/udev_disk_hook.sh %k noreplace"

View File

@@ -0,0 +1,69 @@
#!/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
if is_ventoy_hook_finished; then
exit 0
fi
vtlog "##### INOTIFYD: $2/$3 is created ..."
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
if is_inotify_ventoy_part $3; then
vtlog "find ventoy partition ..."
$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 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})
vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $AWK '{print $2}' | $SED 's/.*"\(.*\)".*/\1/')
vtlog "blkdev_num=$blkdev_num vtDM=$vtDM label $vtLABEL ..."
if [ -n "$vtLABEL" ]; then
$BUSYBOX_PATH/mkdir -p /dev/disk/by-label/
ln -s /dev/$vtDM /dev/disk/by-label/$vtLABEL
fi
#
# cheatcode for mageia
#
# From mageia/soft/drakx/mdk-stage1 source code, we see that the stage1 binary will search
# /tmp/syslog file to determin whether there is a DAC960 cdrom in the system.
# So we insert some string to /tmp/syslog file to cheat the stage1 program.
#
$BUSYBOX_PATH/mkdir -p /dev/rd
ventoy_copy_device_mapper "/dev/rd/ventoy"
echo 'ventoy cheatcode /dev/rd/ventoy: model' >> /tmp/syslog
if [ -e /sbin/mgalive-root ]; then
vtlog "set mgalive-root ..."
$BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid /sbin/blkid
$BUSYBOX_PATH/mkdir -p /dev/mapper
ln -s /dev/$vtDM /dev/mapper/ventoy
/sbin/mgalive-root /dev/dm-0
fi
set_ventoy_hook_finish
fi
PATH=$VTPATH_OLD

View File

@@ -0,0 +1,31 @@
#!/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
vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt)
vtdisk=$(get_ventoy_disk_name)
if [ "$vtdisk" = "unknown" ]; then
vtlog "... start inotifyd listen $vtHook ..."
$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- &
else
vtlog "... $vtdisk already exist ..."
$BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2"
fi

View File

@@ -64,7 +64,7 @@ fi
#some distro add there repo file to /etc/anaconda.repos.d/ which will cause error during installation #some distro add there repo file to /etc/anaconda.repos.d/ which will cause error during installation
$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $VTOY_PATH/hook/rhel6/anaconda-repo-listen.sh /etc/anaconda.repos.d:n & #$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $VTOY_PATH/hook/rhel6/anaconda-repo-listen.sh /etc/anaconda.repos.d:n &
ventoy_udev_disk_common_hook $* "noreplace" ventoy_udev_disk_common_hook $* "noreplace"

View File

@@ -22,6 +22,5 @@
$BUSYBOX_PATH/mkdir -p /etc/anaconda.repos.d /mnt/ventoy $BUSYBOX_PATH/mkdir -p /etc/anaconda.repos.d /mnt/ventoy
ventoy_print_yum_repo "ventoy" "file:///mnt/ventoy" > /etc/anaconda.repos.d/ventoy.repo ventoy_print_yum_repo "ventoy" "file:///mnt/ventoy" > /etc/anaconda.repos.d/ventoy.repo
ventoy_add_udev_rule "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" ventoy_add_udev_rule "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k"
ventoy_add_kernel_udev_rule "loop7" "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" ventoy_add_kernel_udev_rule "loop7" "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k"

View File

@@ -31,6 +31,12 @@ else
VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs" VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs"
break break
fi fi
if echo $vtParam | $GREP -q '^ks=.*:/'; then
vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}')
VTKS="ks=hd:/dev/dm-0:$vtRawKs"
break
fi
done done
fi fi
@@ -44,8 +50,15 @@ fi
ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh #Fedora
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/01-ventoy-timeout.sh if $BUSYBOX_PATH/which dmsquash-live-root > /dev/null; then
vtPriority=99
else
vtPriority=01
fi
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh
$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh
# suppress write protected mount warning # suppress write protected mount warning
if [ -e /usr/sbin/anaconda-diskroot ]; then if [ -e /usr/sbin/anaconda-diskroot ]; then

View File

@@ -28,6 +28,16 @@ vtlog "##### INOTIFYD: $2/$3 is created ..."
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
if is_inotify_ventoy_part $3; then if is_inotify_ventoy_part $3; then
vtGenRulFile='/etc/udev/rules.d/99-live-squash.rules'
if [ -e $vtGenRulFile ] && $GREP -q dmsquash $vtGenRulFile; then
vtScript=$($GREP -m1 'RUN.=' $vtGenRulFile | $AWK -F'RUN.=' '{print $2}' | $SED 's/"\(.*\)".*/\1/')
vtlog "vtScript=$vtScript"
$vtScript
else
vtlog "$vtGenRulFile not exist..."
fi
vtlog "find ventoy partition ..." vtlog "find ventoy partition ..."
$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace
@@ -41,8 +51,10 @@ if is_inotify_ventoy_part $3; then
ventoy_swap_device /dev/dm-0 /dev/$vtDM ventoy_swap_device /dev/dm-0 /dev/$vtDM
fi fi
if [ -e /sbin/anaconda-diskroot ]; then
vtlog "set anaconda-diskroot ..." vtlog "set anaconda-diskroot ..."
/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/dm-0 /sbin/anaconda-diskroot /dev/dm-0
fi
set_ventoy_hook_finish set_ventoy_hook_finish
fi fi

View File

@@ -26,7 +26,9 @@ VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/')
vtDM=$(ventoy_find_dm_id ${blkdev_num}) vtDM=$(ventoy_find_dm_id ${blkdev_num})
vtlog "diskroot $vtDM ..." if [ -e /sbin/anaconda-diskroot ]; then
/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/$vtDM vtlog "set anaconda-diskroot ..."
/sbin/anaconda-diskroot /dev/dm-0
fi
PATH=$VTPATH_OLD PATH=$VTPATH_OLD

View File

@@ -51,7 +51,17 @@ fi
# # # #
#################################################################### ####################################################################
cd / cd /
rm -rf /init /linuxrc /sbin /dev/ /root rm -rf /init /linuxrc /dev/ /root
vtSbinFileNum=$(ls -1 /sbin | wc -l)
if [ $vtSbinFileNum -eq 1 ]; then
echo "remove whole sbin directory" >> $VTLOG
rm -rf /sbin
else
echo "remove only sbin/init file" >> $VTLOG
ls -l /sbin >> $VTLOG
rm -f /sbin/init
fi
ventoy_is_initrd_ramdisk() { ventoy_is_initrd_ramdisk() {
#As I known, PCLinuxOS use ramdisk #As I known, PCLinuxOS use ramdisk

View File

@@ -87,6 +87,10 @@ ventoy_get_os_type() {
elif $EGREP -q 'archlinux|ARCH' /proc/version; then elif $EGREP -q 'archlinux|ARCH' /proc/version; then
echo 'arch'; return echo 'arch'; return
# kiosk
elif $EGREP -q 'kiosk' /proc/version; then
echo 'kiosk'; return
# gentoo # gentoo
elif $EGREP -q '[Gg]entoo' /proc/version; then elif $EGREP -q '[Gg]entoo' /proc/version; then
echo 'gentoo'; return echo 'gentoo'; return
@@ -184,6 +188,10 @@ ventoy_get_os_type() {
fi fi
fi fi
if $GREP -q 'android.x86' /proc/version; then
echo 'android'; return
fi
echo "default" echo "default"
} }
@@ -211,7 +219,6 @@ if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then
fi fi
#################################################################### ####################################################################
# # # #
# Step 4 : Hand over to real init # # Step 4 : Hand over to real init #

View File

@@ -0,0 +1,77 @@
#!/bin/sh
size=1024
fstype=ext4
label=casper-rw
print_usage() {
echo 'Usage: CreatePersistentImg.sh [ -s size ] [ -t fstype ] [ -l LABEL ]'
echo ' OPTION: (optional)'
echo ' -s size in MB, default is 1024'
echo ' -t filesystem type, default is ext4 ext2/ext3/ext4/xfs are supported now'
echo ' -l label, default is casper-rw'
echo ''
}
while [ -n "$1" ]; do
if [ "$1" = "-s" ]; then
shift
size=$1
elif [ "$1" = "-t" ]; then
shift
fstype=$1
elif [ "$1" = "-l" ]; then
shift
label=$1
else
print_usage
exit 1
fi
shift
done
# check label
if [ -z "$label" ]; then
echo "The label can NOT be empty."
exit 1
fi
# check size
if echo $size | grep -q "^[0-9][0-9]*$"; then
if [ $size -le 1 ]; then
echo "Invalid size $size"
exit 1
fi
else
echo "Invalid size $size"
exit 1
fi
# check file system type
# nodiscard must be set for ext2/3/4
# -K must be set for xfs
if echo $fstype | grep -q '^ext[234]$'; then
fsopt='-E nodiscard'
elif [ "$fstype" = "xfs" ]; then
fsopt='-K'
else
echo "unsupported file system $fstype"
exit 1
fi
# 00->ff avoid sparse file
dd if=/dev/zero bs=1M count=$size | tr '\000' '\377' > persistence.img
sync
freeloop=$(losetup -f)
losetup $freeloop persistence.img
mkfs -t $fstype $fsopt -L $label $freeloop
sync
losetup -d $freeloop

Binary file not shown.

Binary file not shown.

View File

@@ -1,25 +1,5 @@
#!/bin/sh #!/bin/sh
OLDDIR=$PWD
if ! [ -f ./tool/ventoy_lib.sh ]; then
cd ${0%Ventoy2Disk.sh}
fi
. ./tool/ventoy_lib.sh
print_usage() {
echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX'
echo ' CMD:'
echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)'
echo ' -u update ventoy in sdX'
echo ' -I force install ventoy to sdX (no matter installed or not)'
echo ''
echo ' OPTION: (optional)'
echo ' -s enable secure boot support (default is disabled)'
echo ''
}
echo '' echo ''
echo '***********************************************************' echo '***********************************************************'
@@ -28,324 +8,43 @@ echo '* longpanda admin@ventoy.net *'
echo '***********************************************************' echo '***********************************************************'
echo '' echo ''
vtdebug "############# Ventoy2Disk $0 ################" OLDDIR=$PWD
while [ -n "$1" ]; do if ! [ -f ./tool/xzcat ]; then
if [ "$1" = "-i" ]; then if [ -f ${0%Ventoy2Disk.sh}/tool/xzcat ]; then
MODE="install" cd ${0%Ventoy2Disk.sh}
elif [ "$1" = "-I" ]; then
MODE="install"
FORCE="Y"
elif [ "$1" = "-u" ]; then
MODE="update"
elif [ "$1" = "-s" ]; then
SECUREBOOT="YES"
else
if ! [ -b "$1" ]; then
vterr "$1 is NOT a valid device"
print_usage
cd $OLDDIR
exit 1
fi fi
DISK=$1
fi fi
shift
done
if [ -z "$MODE" ]; then
print_usage
cd $OLDDIR
exit 1
fi
if ! [ -b "$DISK" ]; then
vterr "Disk $DISK does not exist"
cd $OLDDIR
exit 1
fi
if [ -e /sys/class/block/${DISK#/dev/}/start ]; then
vterr "$DISK is a partition, please use the whole disk"
cd $OLDDIR
exit 1
fi
if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then
vtdebug "root permission check ok ..."
else
vterr "Failed to access $DISK, maybe root privilege is needed!"
echo ''
cd $OLDDIR
exit 1
fi
vtdebug "MODE=$MODE FORCE=$FORCE"
if ! [ -f ./boot/boot.img ]; then if ! [ -f ./boot/boot.img ]; then
if [ -d ./grub ]; then if [ -d ./grub ]; then
vterr "Don't run me here, please download the released install package, and run there." echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it."
else else
vterr "Please run under the right directory!" echo "Please run under the correct directory!"
fi fi
exit 1 exit 1
fi fi
echo "############# Ventoy2Disk $* ################" >> ./log.txt
#decompress tool #decompress tool
if ! [ -f ./tool/ash ]; then
cd tool cd tool
chmod +x ./xzcat chmod +x ./xzcat
for file in $(ls); do for file in $(ls *.xz); do
if [ "$file" != "xzcat" ]; then
if [ "$file" != "ventoy_lib.sh" ]; then
./xzcat $file > ${file%.xz} ./xzcat $file > ${file%.xz}
chmod +x ${file%.xz} chmod +x ${file%.xz}
fi
fi
done done
cd ../ cd ../
if ! check_tool_work_ok; then if ! [ -f ./tool/ash ]; then
vterr "Some tools can not run in current system. Please check log.txt for detail." echo 'Failed to decompress tools ...'
cd $OLDDIR
exit 1
fi
grep "^$DISK" /proc/mounts | while read mtline; do
mtpnt=$(echo $mtline | awk '{print $2}')
vtdebug "Trying to umount $mtpnt ..."
umount $mtpnt >/dev/null 2>&1
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
vterr "$DISK is already mounted, please umount it first!"
cd $OLDDIR
exit 1
fi
if swapon -s | grep -q "^${DISK}[0-9]"; then
vterr "$DISK is used as swap, please swapoff it first!"
cd $OLDDIR
exit 1
fi
if [ "$MODE" = "install" ]; then
vtdebug "install ventoy ..."
if ! fdisk -v >/dev/null 2>&1; then
vterr "fdisk is needed by ventoy installation, but is not found in the system."
cd $OLDDIR
exit 1
fi
version=$(get_disk_ventoy_version $DISK)
if [ $? -eq 0 ]; then
if [ -z "$FORCE" ]; then
vtwarn "$DISK already contains a Ventoy with version $version"
vtwarn "Use -u option to do a safe upgrade operation."
vtwarn "OR if you really want to reinstall ventoy to $DISK, please use -I option."
vtwarn ""
cd $OLDDIR cd $OLDDIR
exit 1 exit 1
fi fi
fi fi
disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) ./tool/ash ./tool/VentoyWorker.sh $*
disk_size_gb=$(expr $disk_sector_num / 2097152)
if [ $disk_sector_num -gt 4294967296 ]; then
vterr "$DISK is over 2TB size, MBR will not work on it."
cd $OLDDIR
exit 1
fi
#Print disk info
echo "Disk : $DISK"
parted -s $DISK p 2>&1 | grep Model
echo "Size : $disk_size_gb GB"
echo ''
vtwarn "Attention:"
vtwarn "You will install Ventoy to $DISK."
vtwarn "All the data on the disk $DISK will be lost!!!"
echo ""
read -p 'Continue? (y/n)' Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
exit 0
fi
fi
echo ""
vtwarn "All the data on the disk $DISK will be lost!!!"
read -p 'Double-check. Continue? (y/n)' Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
exit 0
fi
fi
if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
vterr "No enough space in disk $DISK"
exit 1
fi
if ! dd if=/dev/zero of=$DISK bs=1 count=512 status=none conv=fsync; then
vterr "Write data to $DISK failed, please check whether it's in use."
exit 1
fi
format_ventoy_disk $DISK
# format part1
if ventoy_is_linux64; then
cmd=./tool/mkexfatfs_64
else
cmd=./tool/mkexfatfs_32
fi
chmod +x ./tool/*
# DiskSize > 32GB Cluster Size use 128KB
# DiskSize < 32GB Cluster Size use 32KB
if [ $disk_size_gb -gt 32 ]; then
cluster_sectors=256
else
cluster_sectors=64
fi
$cmd -n ventoy -s $cluster_sectors ${DISK}1
chmod +x ./tool/vtoy_gen_uuid
vtinfo "writing data to disk ..."
dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
./tool/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
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
#disk signature
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4
vtinfo "sync data ..."
sync
vtinfo "esp partition processing ..."
sleep 1
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
if [ -n "$mtpnt" ]; then
umount $mtpnt >/dev/null 2>&1
fi
if [ "$SECUREBOOT" != "YES" ]; then
mkdir ./tmp_mnt
vtdebug "mounting part2 ...."
for tt in 1 2 3; do
if mount ${DISK}2 ./tmp_mnt; then
vtdebug "mounting part2 success"
break
fi
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
if [ -n "$mtpnt" ]; then
umount $mtpnt >/dev/null 2>&1
fi
sleep 2
done
rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi
rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi
rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer
mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
umount ./tmp_mnt
rm -rf ./tmp_mnt
fi
echo ""
vtinfo "Install Ventoy to $DISK successfully finished."
echo ""
else
vtdebug "update ventoy ..."
oldver=$(get_disk_ventoy_version $DISK)
if [ $? -ne 0 ]; then
vtwarn "$DISK does not contain ventoy or data corupted"
echo ""
vtwarn "Please use -i option if you want to install ventoy to $DISK"
echo ""
cd $OLDDIR
exit 1
fi
curver=$(cat ./ventoy/version)
vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!"
echo ""
read -p "Update Ventoy $oldver ===> $curver Continue? (y/n)" Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
cd $OLDDIR
exit 0
fi
fi
PART2=$(get_disk_part_name $DISK 2)
dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size)
part2_start=$(expr $disk_sector_num - $VENTOY_SECTOR_NUM)
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
sync
if [ "$SECUREBOOT" != "YES" ]; then
mkdir ./tmp_mnt
vtdebug "mounting part2 ...."
for tt in 1 2 3; do
if mount ${DISK}2 ./tmp_mnt; then
vtdebug "mounting part2 success"
break
fi
sleep 2
done
rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi
rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi
rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer
mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
umount ./tmp_mnt
rm -rf ./tmp_mnt
fi
echo ""
vtinfo "Update Ventoy to $DISK successfully finished."
echo ""
fi
cd $OLDDIR cd $OLDDIR

57
INSTALL/grub/debug.cfg Normal file
View File

@@ -0,0 +1,57 @@
submenu 'Check plugin json configuration (ventoy.json)' {
menuentry 'Check global control plugin configuration' {
set pager=1
vt_check_plugin_json $iso_path control $iso_path
echo -e "\npress ENTER to exit ..."
read vtInputKey
unset pager
}
menuentry 'Check theme plugin configuration' {
set pager=1
vt_check_plugin_json $iso_path theme $iso_path
echo -e "\npress ENTER to exit ..."
read vtInputKey
unset pager
}
menuentry 'Check auto install plugin configuration' {
set pager=1
vt_check_plugin_json $iso_path auto_install $iso_path
echo -e "\npress ENTER to exit ..."
read vtInputKey
unset pager
}
menuentry 'Check persistence plugin configuration' {
set pager=1
vt_check_plugin_json $iso_path persistence $iso_path
echo -e "\n############### dump persistence ###############"
vt_dump_persistence
echo -e "\npress ENTER to exit ..."
read vtInputKey
unset pager
}
menuentry 'Check menu alias plugin configuration' {
set pager=1
vt_check_plugin_json $iso_path menu_alias $iso_path
echo -e "\npress ENTER to exit ..."
read vtInputKey
unset pager
}
menuentry 'Return to previous menu [Esc]' VTOY_RET {
echo 'Return ...'
}
}
menuentry 'Return to previous menu [Esc]' VTOY_RET {
echo 'Return ...'
}

Binary file not shown.

Binary file not shown.

View File

@@ -16,30 +16,38 @@
# #
#************************************************************************************ #************************************************************************************
function ventoy_power { function ventoy_pause {
echo '<1> Reboot' if [ -n "${vtdebug_flag}" ]; then
echo '<2> Halt' echo "press Enter to continue ......"
echo '<0> Return to menu' read vtTmpPause
echo -e '\nPlease enter your choice:'
unset vtOpt
read vtOpt
if [ "$vtOpt" = "1" ]; then
echo -e '\n\nSystem is rebooting ... \n'
sleep 1
reboot
elif [ "$vtOpt" = "2" ]; then
echo -e '\n\nSystem is halting ... \n'
sleep 1
halt
fi fi
} }
function ventoy_debug_pause {
if [ -n "${vtdebug_flag}" ]; then
echo "press Enter to continue ......"
read vtTmpPause
fi
}
function ventoy_power {
configfile $prefix/power.cfg
}
function ventoy_diagnosis {
configfile $prefix/debug.cfg
}
function ventoy_localboot {
configfile $prefix/localboot.cfg
}
function get_os_type { function get_os_type {
set vtoy_os=Linux set vtoy_os=Linux
for file in "efi/microsoft" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com" "BOOT/etfsboot.com"; do
if [ -e $1/$file ]; then for file in "efi/microsoft/boot/bcd" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com" ; do
if vt_file_exist_nocase (loop)/$file; then
set vtoy_os=Windows set vtoy_os=Windows
break break
fi fi
@@ -50,18 +58,10 @@ function get_os_type {
fi fi
} }
function vt_check_pe { function vt_check_compatible_pe {
unset VT_PE_SUPPORT #Check for PE without external tools
if [ -f $1/HBCD_PE.ini ]; then if [ -f $1/HBCD_PE.ini ]; then
set ventoy_compatible=YES set ventoy_compatible=YES
set VT_PE_SUPPORT=YES
elif [ -f $1/easyu.flg ]; then
set VT_PE_SUPPORT=YES
elif [ -f $1/USM.ICO ]; then
set VT_PE_SUPPORT=YES
elif [ -d $1/USM_TOOL ]; then
set VT_PE_SUPPORT=YES
fi fi
} }
@@ -70,22 +70,37 @@ function locate_initrd {
if [ -n "${vtdebug_flag}" ]; then if [ -n "${vtdebug_flag}" ]; then
vt_linux_dump_initrd vt_linux_dump_initrd
sleep 5 ventoy_debug_pause
fi fi
} }
function find_wim_file { function locate_wim {
unset ventoy_wim_file vt_windows_locate_wim_patch (loop)
for file in "sources/boot.wim" "sources/BOOT.WIM" "Sources/Win10PEx64.WIM" "boot/BOOT.WIM" \ if [ -n "${vtdebug_flag}" ]; then
"winpe_x64.wim" "boot/10pex64.wim" "BOOT/USM1PE6L.WIM" "BOOT/USM1PE6F.WIM"; do echo '###############################################'
if [ -e $1/$file ]; then vt_dump_wim_patch
set ventoy_wim_file=$1/$file echo '###############################################'
break ventoy_debug_pause
fi fi
done
} }
function distro_specify_wim_patch {
if [ -d (loop)/h3pe ]; then
vt_windows_collect_wim_patch wim /BOOT/H3_10PE.WIM
vt_windows_collect_wim_patch wim /BOOT/H3_7PE.WIM
vt_windows_collect_wim_patch wim /BOOT/H3_8PE.WIM
vt_windows_collect_wim_patch wim /BOOT/H3_81PE.WIM
fi
}
function distro_specify_wim_patch_phase2 {
if [ -f (loop)/boot/boot.wim ]; then
vt_windows_collect_wim_patch wim /boot/boot.wim
fi
}
function distro_specify_initrd_file { function distro_specify_initrd_file {
if [ -e (loop)/boot/all.rdz ]; then if [ -e (loop)/boot/all.rdz ]; then
vt_linux_specify_initrd_file /boot/all.rdz vt_linux_specify_initrd_file /boot/all.rdz
@@ -135,6 +150,8 @@ function distro_specify_initrd_file_phase2 {
vt_linux_specify_initrd_file /initrd-x86_64 vt_linux_specify_initrd_file /initrd-x86_64
elif [ -f (loop)/live/initrd.img ]; then elif [ -f (loop)/live/initrd.img ]; then
vt_linux_specify_initrd_file /live/initrd.img vt_linux_specify_initrd_file /live/initrd.img
elif [ -f (loop)/initrd.img ]; then
vt_linux_specify_initrd_file /initrd.img
fi fi
} }
@@ -143,17 +160,28 @@ function uefi_windows_menu_func {
vt_windows_reset vt_windows_reset
if [ "$ventoy_compatible" = "NO" ]; then if [ "$ventoy_compatible" = "NO" ]; then
find_wim_file (loop)
if [ -n "$ventoy_wim_file" ]; then if [ "$ventoy_fs_probe" = "iso9660" ]; then
vt_windows_locate_wim $ventoy_wim_file loopback -d loop
vt_iso9660_nojoliet 1
loopback loop $1$2
fi fi
for file in "efi/microsoft/boot/bcd"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
fi
ventoy_debug_pause
locate_wim
fi fi
vt_windows_chain_data ${1}${chosen_path} vt_windows_chain_data ${1}${chosen_path}
ventoy_debug_pause
if [ -n "${vtdebug_flag}" ]; then
sleep 5
fi
if [ -n "$vtoy_chain_mem_addr" ]; then if [ -n "$vtoy_chain_mem_addr" ]; then
terminal_output console terminal_output console
@@ -161,12 +189,19 @@ function uefi_windows_menu_func {
boot boot
else else
echo "chain empty failed" echo "chain empty failed"
sleep 5 ventoy_pause
fi fi
} }
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
loopback -d loop
set ventoy_fs_probe=iso9660
loopback loop $1$2
fi
vt_load_cpio ${vtoy_path}/ventoy.cpio $2 $1 vt_load_cpio ${vtoy_path}/ventoy.cpio $2 $1
vt_linux_clear_initrd vt_linux_clear_initrd
@@ -183,17 +218,11 @@ function uefi_linux_menu_func {
# special process for special distros # special process for special distros
if [ -d (loop)/loader/entries ]; then if [ -d (loop)/loader/entries ]; then
set LoadIsoEfiDriver=on
vt_linux_parse_initrd_grub dir (loop)/loader/entries/ vt_linux_parse_initrd_grub dir (loop)/loader/entries/
elif [ -d (loop)/boot/grub ]; then elif [ -d (loop)/boot/grub ]; then
vt_linux_parse_initrd_grub dir (loop)/boot/grub/ vt_linux_parse_initrd_grub dir (loop)/boot/grub/
fi fi
if [ -e (loop)/syslinux/alt0/full.cz ]; then
set LoadIsoEfiDriver=on
set FirstTryBootFile='@EFI@BOOT@grubx64.efi'
fi
distro_specify_initrd_file distro_specify_initrd_file
vt_linux_initrd_count vtcount vt_linux_initrd_count vtcount
@@ -208,6 +237,24 @@ function uefi_linux_menu_func {
fi fi
locate_initrd locate_initrd
if [ -d (loop)/loader/entries ]; then
vt_linux_get_main_initrd_index vtindex
if [ -d (loop)/arch ]; then
if [ -f (loop)/arch/boot/x86_64/archiso.img ]; then
vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img"
elif [ -f (loop)/boot/initramfs_x86_64.img ]; then
vt_add_replace_file $vtindex "boot\\initramfs_x86_64.img"
fi
elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then
vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz"
fi
elif [ -e (loop)/syslinux/alt0/full.cz ]; then
vt_add_replace_file 0 "EFI\\BOOT\\full.cz"
set FirstTryBootFile='@EFI@BOOT@grubx64.efi'
fi
fi fi
vt_linux_chain_data ${1}${chosen_path} vt_linux_chain_data ${1}${chosen_path}
@@ -218,7 +265,7 @@ function uefi_linux_menu_func {
boot boot
else else
echo "chain empty failed" echo "chain empty failed"
sleep 5 ventoy_pause
fi fi
} }
@@ -239,11 +286,14 @@ function uefi_iso_menu_func {
fi fi
vt_chosen_img_path chosen_path vt_chosen_img_path chosen_path
vt_select_auto_install ${chosen_path}
vt_select_persistence ${chosen_path}
if vt_is_udf ${1}${chosen_path}; then if vt_is_udf ${1}${chosen_path}; then
set ventoy_fs_probe=udf set ventoy_fs_probe=udf
else else
set ventoy_fs_probe=iso9660 set ventoy_fs_probe=iso9660
vt_iso9660_nojoliet 0
fi fi
loopback loop ${1}${chosen_path} loopback loop ${1}${chosen_path}
@@ -269,13 +319,7 @@ function uefi_iso_menu_func {
vt_img_sector ${1}${chosen_path} vt_img_sector ${1}${chosen_path}
if [ "$vtoy_os" = "Windows" ]; then if [ "$vtoy_os" = "Windows" ]; then
vt_check_pe (loop) vt_check_compatible_pe (loop)
if [ "$VT_PE_SUPPORT" != "YES" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
set ventoy_compatible=YES
fi
fi
uefi_windows_menu_func $1 ${chosen_path} uefi_windows_menu_func $1 ${chosen_path}
else else
uefi_linux_menu_func $1 ${chosen_path} uefi_linux_menu_func $1 ${chosen_path}
@@ -300,31 +344,49 @@ function legacy_windows_menu_func {
vt_windows_reset vt_windows_reset
if [ "$ventoy_compatible" = "NO" ]; then if [ "$ventoy_compatible" = "NO" ]; then
find_wim_file (loop)
if [ -n "$ventoy_wim_file" ]; then if [ "$ventoy_fs_probe" = "iso9660" ]; then
vt_windows_locate_wim $ventoy_wim_file loopback -d loop
elif [ -n "${vtdebug_flag}" ]; then vt_iso9660_nojoliet 1
echo No wim file found loopback loop $1$2
fi fi
for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
distro_specify_wim_patch
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
fi
ventoy_debug_pause
locate_wim
fi fi
vt_windows_chain_data ${1}${chosen_path} vt_windows_chain_data ${1}${chosen_path}
ventoy_debug_pause
if [ -n "${vtdebug_flag}" ]; then
sleep 5
fi
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} 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"
sleep 5 ventoy_pause
fi fi
} }
function legacy_linux_menu_func { function legacy_linux_menu_func {
if [ "$ventoy_compatible" = "NO" ]; then if [ "$ventoy_compatible" = "NO" ]; then
if [ "$ventoy_fs_probe" = "udf" ]; then
loopback -d loop
set ventoy_fs_probe=iso9660
loopback loop $1$2
fi
vt_load_cpio $vtoy_path/ventoy.cpio $2 $1 vt_load_cpio $vtoy_path/ventoy.cpio $2 $1
vt_linux_clear_initrd vt_linux_clear_initrd
@@ -365,17 +427,14 @@ function legacy_linux_menu_func {
fi fi
vt_linux_chain_data ${1}${chosen_path} vt_linux_chain_data ${1}${chosen_path}
ventoy_debug_pause
if [ -n "${vtdebug_flag}" ]; then
sleep 5
fi
if [ -n "$vtoy_chain_mem_addr" ]; then if [ -n "$vtoy_chain_mem_addr" ]; 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}
boot boot
else else
echo "chain empty failed" echo "chain empty failed"
sleep 5 ventoy_pause
fi fi
} }
@@ -386,15 +445,17 @@ function legacy_iso_menu_func {
fi fi
vt_chosen_img_path chosen_path vt_chosen_img_path chosen_path
vt_select_auto_install ${chosen_path}
vt_select_persistence ${chosen_path}
if vt_is_udf ${1}${chosen_path}; then if vt_is_udf ${1}${chosen_path}; then
set ventoy_fs_probe=udf set ventoy_fs_probe=udf
else else
set ventoy_fs_probe=iso9660 set ventoy_fs_probe=iso9660
vt_iso9660_nojoliet 0
fi fi
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
@@ -409,13 +470,7 @@ function legacy_iso_menu_func {
vt_img_sector ${1}${chosen_path} vt_img_sector ${1}${chosen_path}
if [ "$vtoy_os" = "Windows" ]; then if [ "$vtoy_os" = "Windows" ]; then
vt_check_pe (loop) vt_check_compatible_pe (loop)
if [ "$VT_PE_SUPPORT" != "YES" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
set ventoy_compatible=YES
fi
fi
legacy_windows_menu_func $1 ${chosen_path} legacy_windows_menu_func $1 ${chosen_path}
else else
legacy_linux_menu_func $1 ${chosen_path} legacy_linux_menu_func $1 ${chosen_path}
@@ -431,7 +486,7 @@ function legacy_iso_memdisk {
boot boot
} }
function common_menuentry { function iso_common_menuentry {
if [ "$grub_platform" = "pc" ]; then if [ "$grub_platform" = "pc" ]; then
if vt_check_mode 0; then if vt_check_mode 0; then
legacy_iso_memdisk $iso_path legacy_iso_memdisk $iso_path
@@ -447,6 +502,38 @@ function common_menuentry {
fi fi
} }
function iso_unsupport_menuentry {
echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n"
echo -e "\n Will return to main menu after 10 seconds ...\n"
sleep 10
}
function wim_common_menuentry {
vt_chosen_img_path chosen_path
vt_wim_chain_data ${iso_path}${chosen_path}
ventoy_debug_pause
if [ -n "$vtoy_chain_mem_addr" ]; then
if [ "$grub_platform" = "pc" ]; then
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
else
terminal_output 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}
fi
boot
else
echo "chain empty failed"
ventoy_pause
fi
}
function wim_unsupport_menuentry {
echo -e "\n The name of the wim file could NOT contain space or non-ascii characters. \n"
echo -e "\n Will return to main menu after 10 seconds ...\n"
sleep 10
}
############################################################# #############################################################
############################################################# #############################################################
@@ -456,7 +543,7 @@ function common_menuentry {
############################################################# #############################################################
############################################################# #############################################################
set VENTOY_VERSION="1.0.11" set VENTOY_VERSION="1.0.13"
# 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
@@ -466,11 +553,13 @@ set VTOY_DEFAULT_MENU_MODE=0
#disable timeout #disable timeout
unset timeout unset timeout
set VTOY_MEM_DISK_STR="MEMDISK" set VTOY_MEM_DISK_STR="[Memdisk]"
set VTOY_ISO_RAW_STR="ISO RAW" set VTOY_ISO_RAW_STR="Compatible Mode"
set VTOY_ISO_UEFI_DRV_STR="UEFI FS" set VTOY_ISO_UEFI_DRV_STR="UEFI FS"
set VTOY_F2_CMD="ventoy_power" set VTOY_F2_CMD="ventoy_power"
set VTOY_F4_CMD="ventoy_localboot"
set VTOY_F5_CMD="ventoy_diagnosis"
if [ "$grub_platform" = "pc" ]; then if [ "$grub_platform" = "pc" ]; then
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net" set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net"
@@ -485,28 +574,42 @@ if [ "$vtoy_dev" = "tftp" ]; then
for vtid in 0 1 2 3; do for vtid in 0 1 2 3; do
if [ -d (hd$vtid,2)/ventoy ]; then if [ -d (hd$vtid,2)/ventoy ]; then
set iso_path=(hd$vtid,1) set iso_path=(hd$vtid,1)
set vtoy_efi_part=(hd$vtid,2)
break break
fi fi
done done
loadfont ascii
else
if [ "$prefix" = "(ventoydisk)/grub" ]; then
set vtoy_path=(ventoydisk)/ventoy
else else
set vtoy_path=($root)/ventoy set vtoy_path=($root)/ventoy
set iso_path=($vtoy_dev,1)
fi fi
loadfont ascii set iso_path=($vtoy_dev,1)
set vtoy_efi_part=($vtoy_dev,2)
loadfont unicode
fi
#Load Plugin #Load Plugin
if [ -f $iso_path/ventoy/ventoy.json ]; then if [ -f $iso_path/ventoy/ventoy.json ]; then
vt_load_plugin $iso_path vt_load_plugin $iso_path
fi fi
if [ -f $iso_path/ventoy/ventoy_wimboot.img ]; then
vt_load_wimboot $iso_path/ventoy/ventoy_wimboot.img
elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then
vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.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" set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Debug"
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" set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Debug"
fi fi
@@ -522,7 +625,13 @@ else
set theme=$prefix/themes/ventoy/theme.txt set theme=$prefix/themes/ventoy/theme.txt
fi fi
if [ "$vtoy_display_mode" = "CLI" ]; then
terminal_output console
else
terminal_output gfxterm terminal_output gfxterm
fi
#vtdebug on
#colect all image files (iso files) #colect all image files (iso files)
set ventoy_img_count=0 set ventoy_img_count=0
@@ -536,7 +645,14 @@ if [ $ventoy_img_count -gt 0 ]; then
vt_dynamic_menu 0 1 vt_dynamic_menu 0 1
fi fi
else else
menuentry "No ISO files found (Press enter to reboot ...)" { if [ -n "$VTOY_NO_ISO_TIP" ]; then
NO_ISO_MENU="No ISO files found, $VTOY_NO_ISO_TIP"
elif [ -n "$VTOY_DEFAULT_SEARCH_ROOT" ]; then
NO_ISO_MENU="No ISO files found, please check VTOY_DEFAULT_SEARCH_ROOT"
else
NO_ISO_MENU="No ISO files found"
fi
menuentry "$NO_ISO_MENU (Press enter to reboot ...)" {
echo -e "\n Rebooting ... " echo -e "\n Rebooting ... "
reboot reboot
} }

Binary file not shown.

View File

@@ -0,0 +1,57 @@
if [ "$grub_platform" = "pc" ]; then
menuentry 'Search and boot Windows' {
if search -n -s -f /bootmgr; then
ntldr /bootmgr
elif search -n -s -f /ntldr; then
ntldr /ntldr
else
echo "Windows NOT found ..."
fi
}
menuentry 'Boot the 1st local disk' {
set root=(hd0,1)
chainloader +1
boot
}
menuentry 'Boot the 2nd local disk' {
set root=(hd1,1)
chainloader +1
boot
}
menuentry 'Boot the 3rd local disk' {
set root=(hd2,1)
chainloader +1
boot
}
else
menuentry 'Search and boot Windows' {
if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then
terminal_output console
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
boot
else
echo "Windows NOT found ..."
fi
}
menuentry 'Search and boot BOOTX64.EFI' {
if search -n -s -f /efi/boot/bootx64.efi; then
terminal_output console
chainloader /efi/boot/bootx64.efi
boot
else
echo "BOOTX64.EFI NOT found ..."
fi
}
fi
menuentry 'Return to menu [Esc]' VTOY_RET {
echo 'Return ...'
}

15
INSTALL/grub/power.cfg Normal file
View File

@@ -0,0 +1,15 @@
menuentry Reboot {
echo -e '\n\nSystem is rebooting ... \n'
sleep 1
reboot
}
menuentry Halt {
echo -e '\n\nSystem is halting ... \n'
sleep 1
halt
}
menuentry 'Return to menu [Esc]' VTOY_RET {
echo 'Return ...'
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 257 KiB

View File

@@ -1,9 +1,7 @@
desktop-image: "background.png" desktop-image: "background.png"
title-text: " " title-text: " "
title-font: "ascii"
title-color: "#ffffff" title-color: "#ffffff"
message-font: "ascii"
message-color: "#f2f2f2" message-color: "#f2f2f2"
terminal-box: "terminal_box_*.png" terminal-box: "terminal_box_*.png"
@@ -16,14 +14,12 @@ terminal-box: "terminal_box_*.png"
menu_pixmap_style = "menu_*.png" menu_pixmap_style = "menu_*.png"
item_font = "ascii"
item_color = "#ffffff" item_color = "#ffffff"
item_height = 30 item_height = 30
item_spacing = 1 item_spacing = 1
item_padding = 1 item_padding = 1
selected_item_font = "ascii"
selected_item_color= "#f2f2f2" selected_item_color= "#f2f2f2"
selected_item_pixmap_style = "select_*.png" selected_item_pixmap_style = "select_*.png"
@@ -58,8 +54,8 @@ terminal-box: "terminal_box_*.png"
+ hbox{ + hbox{
left = 90% left = 30%
top = 5 top = 95%-25
width = 10% width = 10%
height = 25 height = 25
+ label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"}
@@ -67,8 +63,8 @@ terminal-box: "terminal_box_*.png"
+ hbox{ + hbox{
left = 90% left = 30%
top = 30 top = 95%-50
width = 10% width = 10%
height = 25 height = 25
+ label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"}

Binary file not shown.

View File

@@ -0,0 +1,315 @@
#!/bin/sh
. ./tool/ventoy_lib.sh
print_usage() {
echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX'
echo ' CMD:'
echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)'
echo ' -u update ventoy in sdX'
echo ' -I force install ventoy to sdX (no matter installed or not)'
echo ''
echo ' OPTION: (optional)'
echo ' -s enable secure boot support (default is disabled)'
echo ''
}
while [ -n "$1" ]; do
if [ "$1" = "-i" ]; then
MODE="install"
elif [ "$1" = "-I" ]; then
MODE="install"
FORCE="Y"
elif [ "$1" = "-u" ]; then
MODE="update"
elif [ "$1" = "-s" ]; then
SECUREBOOT="YES"
else
if ! [ -b "$1" ]; then
vterr "$1 is NOT a valid device"
print_usage
exit 1
fi
DISK=$1
fi
shift
done
if [ -z "$MODE" ]; then
print_usage
exit 1
fi
if ! [ -b "$DISK" ]; then
vterr "Disk $DISK does not exist"
exit 1
fi
if [ -e /sys/class/block/${DISK#/dev/}/start ]; then
vterr "$DISK is a partition, please use the whole disk"
exit 1
fi
if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then
vtdebug "root permission check ok ..."
else
vterr "Failed to access $DISK, maybe root privilege is needed!"
echo ''
exit 1
fi
vtdebug "MODE=$MODE FORCE=$FORCE"
if ! check_tool_work_ok; then
vterr "Some tools can not run in current system. Please check log.txt for detail."
exit 1
fi
grep "^$DISK" /proc/mounts | while read mtline; do
mtpnt=$(echo $mtline | awk '{print $2}')
vtdebug "Trying to umount $mtpnt ..."
umount $mtpnt >/dev/null 2>&1
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
vterr "$DISK is already mounted, please umount it first!"
exit 1
fi
if swapon -s | grep -q "^${DISK}[0-9]"; then
vterr "$DISK is used as swap, please swapoff it first!"
exit 1
fi
if [ "$MODE" = "install" ]; then
vtdebug "install ventoy ..."
if parted -v > /dev/null 2>&1; then
PARTTOOL='parted'
elif fdisk -v >/dev/null 2>&1; then
PARTTOOL='fdisk'
else
vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition."
exit 1
fi
version=$(get_disk_ventoy_version $DISK)
if [ $? -eq 0 ]; then
if [ -z "$FORCE" ]; then
vtwarn "$DISK already contains a Ventoy with version $version"
vtwarn "Use -u option to do a safe upgrade operation."
vtwarn "OR if you really want to reinstall ventoy to $DISK, please use -I option."
vtwarn ""
exit 1
fi
fi
disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size)
disk_size_gb=$(expr $disk_sector_num / 2097152)
if [ $disk_sector_num -gt 4294967296 ]; then
vterr "$DISK is over 2TB size, MBR will not work on it."
exit 1
fi
#Print disk info
echo "Disk : $DISK"
parted -s $DISK p 2>&1 | grep Model
echo "Size : $disk_size_gb GB"
echo ''
vtwarn "Attention:"
vtwarn "You will install Ventoy to $DISK."
vtwarn "All the data on the disk $DISK will be lost!!!"
echo ""
read -p 'Continue? (y/n)' Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
exit 0
fi
fi
echo ""
vtwarn "All the data on the disk $DISK will be lost!!!"
read -p 'Double-check. Continue? (y/n)' Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
exit 0
fi
fi
if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then
vterr "No enough space in disk $DISK"
exit 1
fi
if ! dd if=/dev/zero of=$DISK bs=1 count=512 status=none conv=fsync; then
vterr "Write data to $DISK failed, please check whether it's in use."
exit 1
fi
format_ventoy_disk $DISK $PARTTOOL
# format part1
if ventoy_is_linux64; then
cmd=./tool/mkexfatfs_64
else
cmd=./tool/mkexfatfs_32
fi
chmod +x ./tool/*
# DiskSize > 32GB Cluster Size use 128KB
# DiskSize < 32GB Cluster Size use 32KB
if [ $disk_size_gb -gt 32 ]; then
cluster_sectors=256
else
cluster_sectors=64
fi
$cmd -n ventoy -s $cluster_sectors ${DISK}1
chmod +x ./tool/vtoy_gen_uuid
vtinfo "writing data to disk ..."
dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
./tool/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
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16
#disk signature
./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4
vtinfo "sync data ..."
sync
vtinfo "esp partition processing ..."
sleep 1
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
if [ -n "$mtpnt" ]; then
umount $mtpnt >/dev/null 2>&1
fi
if [ "$SECUREBOOT" != "YES" ]; then
mkdir ./tmp_mnt
vtdebug "mounting part2 ...."
for tt in 1 2 3; do
if mount ${DISK}2 ./tmp_mnt; then
vtdebug "mounting part2 success"
break
fi
mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}')
if [ -n "$mtpnt" ]; then
umount $mtpnt >/dev/null 2>&1
fi
sleep 2
done
rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi
rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi
rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer
mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
umount ./tmp_mnt
rm -rf ./tmp_mnt
fi
echo ""
vtinfo "Install Ventoy to $DISK successfully finished."
echo ""
else
vtdebug "update ventoy ..."
oldver=$(get_disk_ventoy_version $DISK)
if [ $? -ne 0 ]; then
vtwarn "$DISK does not contain ventoy or data corupted"
echo ""
vtwarn "Please use -i option if you want to install ventoy to $DISK"
echo ""
exit 1
fi
curver=$(cat ./ventoy/version)
vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!"
echo ""
read -p "Update Ventoy $oldver ===> $curver Continue? (y/n)" Answer
if [ "$Answer" != "y" ]; then
if [ "$Answer" != "Y" ]; then
exit 0
fi
fi
PART2=$(get_disk_part_name $DISK 2)
dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440
PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"')
PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"')
vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE"
if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then
vtdebug "change 1st partition active, 2nd partition inactive ..."
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
fi
./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1
disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size)
part2_start=$(expr $disk_sector_num - $VENTOY_SECTOR_NUM)
./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start
sync
if [ "$SECUREBOOT" != "YES" ]; then
mkdir ./tmp_mnt
vtdebug "mounting part2 ...."
for tt in 1 2 3; do
if mount ${DISK}2 ./tmp_mnt; then
vtdebug "mounting part2 success"
break
fi
sleep 2
done
rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi
rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi
rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer
mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI
umount ./tmp_mnt
rm -rf ./tmp_mnt
fi
echo ""
vtinfo "Update Ventoy to $DISK successfully finished."
echo ""
fi

BIN
INSTALL/tool/ash Normal file

Binary file not shown.

View File

@@ -22,40 +22,17 @@ ventoy_is_linux64() {
ventoy_false ventoy_false
} }
ventoy_is_dash() {
if [ -L /bin/sh ]; then
vtdst=$(readlink /bin/sh)
if [ "$vtdst" = "dash" ]; then
ventoy_true
return
fi
fi
ventoy_false
}
vtinfo() { vtinfo() {
if ventoy_is_dash; then
echo "\033[32m$*\033[0m"
else
echo -e "\033[32m$*\033[0m" echo -e "\033[32m$*\033[0m"
fi
} }
vtwarn() { vtwarn() {
if ventoy_is_dash; then
echo "\033[33m$*\033[0m"
else
echo -e "\033[33m$*\033[0m" echo -e "\033[33m$*\033[0m"
fi
} }
vterr() { vterr() {
if ventoy_is_dash; then
echo "\033[31m$*\033[0m"
else
echo -e "\033[31m$*\033[0m" echo -e "\033[31m$*\033[0m"
fi
} }
vtdebug() { vtdebug() {
@@ -207,9 +184,10 @@ get_disk_ventoy_version() {
ventoy_false ventoy_false
} }
format_ventoy_disk() { format_ventoy_disk() {
DISK=$1 DISK=$1
PARTTOOL=$2
PART1=$(get_disk_part_name $DISK 1) PART1=$(get_disk_part_name $DISK 1)
PART2=$(get_disk_part_name $DISK 2) PART2=$(get_disk_part_name $DISK 2)
@@ -220,15 +198,33 @@ format_ventoy_disk() {
export part2_start_sector=$(expr $part1_end_sector + 1) export part2_start_sector=$(expr $part1_end_sector + 1)
part2_end_sector=$(expr $sector_num - 1) part2_end_sector=$(expr $sector_num - 1)
vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector"
vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector"
if [ -e $PART2 ]; then if [ -e $PART2 ]; then
echo "delete $PART2" echo "delete $PART2"
rm -f $PART2 rm -f $PART2
fi fi
echo "" echo ""
echo "Create partitions on $DISK ..." echo "Create partitions on $DISK by $PARTTOOL ..."
fdisk $DISK >/dev/null 2>&1 <<EOF if [ "$PARTTOOL" = "parted" ]; then
vtdebug "format disk by parted ..."
parted -a none --script $DISK \
mklabel msdos \
unit s \
mkpart primary ntfs $part1_start_sector $part1_end_sector \
mkpart primary fat16 $part2_start_sector $part2_end_sector \
set 1 boot on \
quit
sync
echo -en '\xEF' | dd of=$DISK conv=fsync bs=1 count=1 seek=466 > /dev/null 2>&1
else
vtdebug "format disk by fdisk ..."
fdisk $DISK >>./log.txt 2>&1 <<EOF
o o
n n
p p
@@ -247,14 +243,15 @@ t
2 2
ef ef
a a
2 1
w w
EOF EOF
fi
echo "Done"
udevadm trigger >/dev/null 2>&1 udevadm trigger >/dev/null 2>&1
partprobe >/dev/null 2>&1 partprobe >/dev/null 2>&1
sleep 3 sleep 3
echo "Done"
echo 'mkfs on disk partitions ...' echo 'mkfs on disk partitions ...'
for i in 1 2 3 4 5 6 7; do for i in 1 2 3 4 5 6 7; do
@@ -266,6 +263,7 @@ EOF
fi fi
done done
if ! [ -b $PART2 ]; then if ! [ -b $PART2 ]; then
MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev)
echo "mknod -m 0660 $PART2 b $MajorMinor ..." echo "mknod -m 0660 $PART2 b $MajorMinor ..."
@@ -278,9 +276,9 @@ EOF
fi fi
fi fi
echo "create efi fat fs ..." echo "create efi fat fs $PART2 ..."
for i in 0 1 2 3 4 5 6 7 8 9; do for i in 0 1 2 3 4 5 6 7 8 9; do
if mkfs.vfat -F 16 -n EFI $PART2; then if mkfs.vfat -F 16 -n VTOYEFI $PART2; then
echo 'success' echo 'success'
break break
else else

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,8 @@
#!/bin/sh #!/bin/sh
dos2unix -q ./tool/ventoy_lib.sh
dos2unix -q ./tool/VentoyWorker.sh
. ./tool/ventoy_lib.sh . ./tool/ventoy_lib.sh
GRUB_DIR=../GRUB2/INSTALL GRUB_DIR=../GRUB2/INSTALL
@@ -28,7 +31,7 @@ while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do
sleep 1 sleep 1
done done
format_ventoy_disk $LOOP format_ventoy_disk $LOOP fdisk
$GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP $GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP
@@ -75,7 +78,9 @@ xz --check=crc32 $tmpdir/boot/core.img
cp -a ./tool $tmpdir/ cp -a ./tool $tmpdir/
cp -a Ventoy2Disk.sh $tmpdir/ cp -a Ventoy2Disk.sh $tmpdir/
cp -a CreatePersistentImg.sh $tmpdir/
dos2unix -q $tmpdir/Ventoy2Disk.sh
dos2unix -q $tmpdir/CreatePersistentImg.sh
#32MB disk img #32MB disk img
dd status=none if=$LOOP of=$tmpdir/ventoy/ventoy.disk.img bs=512 count=$VENTOY_SECTOR_NUM skip=$part2_start_sector dd status=none if=$LOOP of=$tmpdir/ventoy/ventoy.disk.img bs=512 count=$VENTOY_SECTOR_NUM skip=$part2_start_sector
@@ -116,4 +121,5 @@ else
exit 1 exit 1
fi fi
rm -f log.txt

View File

@@ -33,6 +33,8 @@ ventoy_img_chunk *g_chunk;
uint32_t g_img_chunk_num; uint32_t g_img_chunk_num;
ventoy_img_chunk *g_cur_chunk; ventoy_img_chunk *g_cur_chunk;
uint32_t g_disk_sector_size; uint32_t g_disk_sector_size;
uint8_t *g_os_param_reserved;
ventoy_override_chunk *g_override_chunk; ventoy_override_chunk *g_override_chunk;
uint32_t g_override_chunk_num; uint32_t g_override_chunk_num;
@@ -42,6 +44,14 @@ uint32_t g_virt_chunk_num;
ventoy_sector_flag g_sector_flag[128]; ventoy_sector_flag g_sector_flag[128];
#define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152
int g_fixup_iso9660_secover_enable = 0;
int g_fixup_iso9660_secover_start = 0;
uint64 g_fixup_iso9660_secover_1st_secs = 0;
uint64 g_fixup_iso9660_secover_cur_secs = 0;
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 )
@@ -195,6 +205,17 @@ static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned lon
memcpy((char *)databuffer, override_data + start - override_start, override_end - start); memcpy((char *)databuffer, override_data + start - override_start, override_end - start);
} }
} }
if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) &&
g_override_chunk[i].override_size == sizeof(ventoy_iso9660_override))
{
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)override_data;
if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW)
{
g_fixup_iso9660_secover_start = 1;
g_fixup_iso9660_secover_cur_secs = 0;
}
}
} }
end: end:
@@ -202,6 +223,59 @@ end:
return 0; return 0;
} }
uint64_t ventoy_fixup_iso9660_sector(uint64_t Lba, uint32_t secNum)
{
uint32_t i = 0;
if (g_fixup_iso9660_secover_cur_secs > 0)
{
Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
g_fixup_iso9660_secover_cur_secs += secNum;
if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
{
g_fixup_iso9660_secover_start = 0;
goto end;
}
}
else
{
ventoy_iso9660_override *dirent;
ventoy_override_chunk *pOverride;
for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
{
dirent = (ventoy_iso9660_override *)pOverride->override_data;
if (Lba == dirent->first_sector)
{
g_fixup_iso9660_secover_start = 0;
goto end;
}
}
if (g_fixup_iso9660_secover_start)
{
for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
{
dirent = (ventoy_iso9660_override *)pOverride->override_data;
if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector)
{
g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048;
g_fixup_iso9660_secover_cur_secs = secNum;
if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
{
g_fixup_iso9660_secover_start = 0;
}
Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
goto end;
}
}
}
}
end:
return Lba;
}
int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int count, unsigned long buffer) int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int count, unsigned long buffer)
{ {
uint32_t i, j; uint32_t i, j;
@@ -223,8 +297,14 @@ 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;
/* Workaround for SSTR PE loader error */
if (g_fixup_iso9660_secover_start)
{
lba = ventoy_fixup_iso9660_sector(lba, count);
}
readend = (lba + count) * 2048; readend = (lba + count) * 2048;
if (readend < g_chain->real_img_size_in_bytes) if (readend <= g_chain->real_img_size_in_bytes)
{ {
ventoy_vdisk_read_real(lba, count, buffer); ventoy_vdisk_read_real(lba, count, buffer);
ix86->regs.dl = sandev->drive; ix86->regs.dl = sandev->drive;
@@ -384,6 +464,8 @@ static void ventoy_dump_chain(ventoy_chain_head *chain)
printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size); printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size);
printf("os_param->vtoy_reserve[0]=<%u>\n", vtoy_reserve[0]); printf("os_param->vtoy_reserve[0]=<%u>\n", vtoy_reserve[0]);
printf("os_param->vtoy_reserve[1]=<%u>\n", vtoy_reserve[1]); printf("os_param->vtoy_reserve[1]=<%u>\n", vtoy_reserve[1]);
printf("os_param->vtoy_reserve[2]=<%u>\n", vtoy_reserve[2]);
printf("os_param->vtoy_reserve[3]=<%u>\n", vtoy_reserve[3]);
printf("os_param->vtoy_img_location_addr=<0x%llx>\n", chain->os_param.vtoy_img_location_addr); printf("os_param->vtoy_img_location_addr=<0x%llx>\n", chain->os_param.vtoy_img_location_addr);
printf("os_param->vtoy_img_location_len=<%u>\n", chain->os_param.vtoy_img_location_len); printf("os_param->vtoy_img_location_len=<%u>\n", chain->os_param.vtoy_img_location_len);
ventoy_debug_pause(); ventoy_debug_pause();
@@ -489,6 +571,14 @@ int ventoy_boot_vdisk(void *data)
g_disk_sector_size = g_chain->disk_sector_size; g_disk_sector_size = g_chain->disk_sector_size;
g_cur_chunk = g_chunk; g_cur_chunk = g_chunk;
g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved);
/* Workaround for Windows & ISO9660 */
if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0)
{
g_fixup_iso9660_secover_enable = 1;
}
g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
g_override_chunk_num = g_chain->override_chunk_num; g_override_chunk_num = g_chain->override_chunk_num;

View File

@@ -85,13 +85,14 @@ struct san_device {
struct list_head opened; struct list_head opened;
/** List of closed SAN paths */ /** List of closed SAN paths */
struct list_head closed; struct list_head closed;
/** SAN paths */
struct san_path path[0];
unsigned int exdrive; unsigned int exdrive;
int int13_command; int int13_command;
void *x86_regptr; void *x86_regptr;
uint8_t boot_catalog_sector[2048]; uint8_t boot_catalog_sector[2048];
/** SAN paths */
struct san_path path[0];
}; };
/** SAN device flags */ /** SAN device flags */

View File

@@ -80,6 +80,14 @@ typedef struct ventoy_os_param
grub_uint8_t reserved[31]; grub_uint8_t reserved[31];
}ventoy_os_param; }ventoy_os_param;
typedef struct ventoy_iso9660_override
{
uint32_t first_sector;
uint32_t first_sector_be;
uint32_t size;
uint32_t size_be;
}ventoy_iso9660_override;
#pragma pack() #pragma pack()
// compile assert to check that size of ventoy_os_param must be 512 // compile assert to check that size of ventoy_os_param must be 512

Binary file not shown.

View File

@@ -15,13 +15,15 @@ See https://www.ventoy.net for detail.
* Legacy + UEFI supported in the same way * Legacy + UEFI supported in the same way
* UEFI Secure Boot supported (since 1.0.07+) * UEFI Secure Boot supported (since 1.0.07+)
* Persistence supported (since 1.0.11+) * Persistence supported (since 1.0.11+)
* WIM files boot supported (Legacy + UEFI) (1.0.12+)
* Auto installation supported (1.0.09+)
* ISO files larger than 4GB supported * ISO files larger than 4GB supported
* Native boot menu style for Legacy & UEFI * Native boot menu style for Legacy & UEFI
* Most type of OS supported, 200+ iso files tested * Most type of OS supported, 200+ iso files tested
* Not only boot but also complete installation process * Not only boot but also complete installation process
* ISO files can be listed in List mode/TreeView mode
* "Ventoy Compatible" concept * "Ventoy Compatible" concept
* Plugin Framework * Plugin Framework
* Auto installation supported (1.0.09+)
* Readonly to USB drive during boot * Readonly to USB drive during boot
* USB normal use unaffected * USB normal use unaffected
* Data nondestructive during version upgrade * Data nondestructive during version upgrade
@@ -33,7 +35,27 @@ See https://www.ventoy.net for detail.
# Installation Instructions # Installation Instructions
See [https://www.ventoy.net/en/doc_start.html](https://www.ventoy.net/en/doc_start.html) for detail See [https://www.ventoy.net/en/doc_start.html](https://www.ventoy.net/en/doc_start.html) for detail
# Compile Instructions # Compile Instructions
Please refer to DOC/BuildVentoyFromSource.txt Please refer to [BuildVentoyFromSource.txt](https://github.com/ventoy/Ventoy/blob/master/DOC/BuildVentoyFromSource.txt)
# Document
Title | Link
-|-
**Install & Update** | [https://www.ventoy.net/en/doc_start.html](https://www.ventoy.net/en/doc_start.html)
**Customize Theme** | [https://www.ventoy.net/en/plugin_theme.html](https://www.ventoy.net/en/plugin_theme.html)
**Auto Installation** | [https://www.ventoy.net/en/plugin_autoinstall.html](https://www.ventoy.net/en/plugin_autoinstall.html)
**Persistence Support** | [https://www.ventoy.net/en/plugin_persistence.html](https://www.ventoy.net/en/plugin_persistence.html)
**Boot WIM file** | [https://www.ventoy.net/en/plugin_wimboot.html](https://www.ventoy.net/en/plugin_wimboot.html)
**Memdisk Mode** | [https://www.ventoy.net/en/doc_memdisk.html](https://www.ventoy.net/en/doc_memdisk.html)
**TreeView Mode** | [https://www.ventoy.net/en/doc_treeview.html](https://www.ventoy.net/en/doc_treeview.html)
**Disk Layout** | [https://www.ventoy.net/en/doc_disk_layout.html](https://www.ventoy.net/en/doc_disk_layout.html)
# FAQ
See [https://www.ventoy.net/en/faq.html](https://www.ventoy.net/en/faq.html) for detail
# Forum
[https://forums.ventoy.net](https://forums.ventoy.net)

View File

@@ -661,6 +661,12 @@ int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount)
continue; continue;
} }
if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))
{
Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size);
continue;
}
pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size); pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size);
if (!pDevDesc) if (!pDevDesc)
{ {
@@ -1585,6 +1591,18 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR); Log("Write Boot Image ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR);
} }
if (0x00 == MBR.PartTbl[0].Active && 0x80 == MBR.PartTbl[1].Active)
{
Log("Need to chage 1st partition active and 2nd partition inactive.");
MBR.PartTbl[0].Active = 0x80;
MBR.PartTbl[1].Active = 0x00;
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
bRet = WriteFile(hDrive, &MBR, 512, &dwSize, NULL);
Log("Write NEW MBR ret:%u dwSize:%u Error:%u", bRet, dwSize, LASTERR);
}
//Refresh Drive Layout //Refresh Drive Layout
DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL); DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);

View File

@@ -449,7 +449,7 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
PartSectorCount = DiskSectorCount - VENTOY_EFI_PART_SIZE / 512 - PartStartSector; PartSectorCount = DiskSectorCount - VENTOY_EFI_PART_SIZE / 512 - PartStartSector;
VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl); VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl);
pMBR->PartTbl[0].Active = 0x00; pMBR->PartTbl[0].Active = 0x80; // bootable
pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS
//Part2 //Part2
@@ -457,7 +457,7 @@ int VentoyFillMBR(UINT64 DiskSizeBytes, MBR_HEAD *pMBR)
PartSectorCount = VENTOY_EFI_PART_SIZE / 512; PartSectorCount = VENTOY_EFI_PART_SIZE / 512;
VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); VentoyFillLocation(DiskSizeBytes, PartStartSector, PartSectorCount, pMBR->PartTbl + 1);
pMBR->PartTbl[1].Active = 0x80; // bootable pMBR->PartTbl[1].Active = 0x00;
pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition
pMBR->Byte55 = 0x55; pMBR->Byte55 = 0x55;

View File

@@ -140,8 +140,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes)
PartStartSector = (UINT32)((SizeBytes - VENTOY_EFI_PART_SIZE) / 512); PartStartSector = (UINT32)((SizeBytes - VENTOY_EFI_PART_SIZE) / 512);
PartSectorCount = VENTOY_EFI_PART_SIZE / 512; PartSectorCount = VENTOY_EFI_PART_SIZE / 512;
if (MBR.PartTbl[1].Active != 0x80 || if (MBR.PartTbl[1].FsFlag != 0xEF ||
MBR.PartTbl[1].FsFlag != 0xEF ||
MBR.PartTbl[1].StartSectorId != PartStartSector || MBR.PartTbl[1].StartSectorId != PartStartSector ||
MBR.PartTbl[1].SectorCount != PartSectorCount) MBR.PartTbl[1].SectorCount != PartSectorCount)
{ {
@@ -149,6 +148,12 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes)
return FALSE; return FALSE;
} }
if (MBR.PartTbl[0].Active != 0x80 && MBR.PartTbl[1].Active != 0x80)
{
Log("Part1 and Part2 are both NOT active 0x%x 0x%x", MBR.PartTbl[0].Active, MBR.PartTbl[1].Active);
return FALSE;
}
Log("PhysicalDrive%d is ventoy disk", PhyDrive); Log("PhysicalDrive%d is ventoy disk", PhyDrive);
return TRUE; return TRUE;
} }

View File

@@ -492,9 +492,9 @@ static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
static CHAR GetMountLogicalDrive(void) static CHAR GetMountLogicalDrive(void)
{ {
CHAR Letter = 'Z'; CHAR Letter = 'Y';
DWORD Drives; DWORD Drives;
DWORD Mask = 0x2000000; DWORD Mask = 0x1000000;
Drives = GetLogicalDrives(); Drives = GetLogicalDrives();
Log("Drives=0x%x", Drives); Log("Drives=0x%x", Drives);