1.0.13 release

This commit is contained in:
longpanda 2020-06-15 01:41:33 +08:00
parent 785255b65f
commit a5c706511b
55 changed files with 3501 additions and 1015 deletions

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)
{ ventoy_delete_ramdisk_param();
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();
} }
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,32 +789,20 @@ 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);
}
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(60);
}
}
ventoy_clean_env(); ventoy_clean_env();
} }
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(30);
}
ventoy_clear_input(); ventoy_clear_input();
gST->ConOut->ClearScreen(gST->ConOut); gST->ConOut->ClearScreen(gST->ConOut);
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,8 +481,10 @@ 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. */
{ {
copy_voldesc = 1; if (0 == g_ventoy_no_joliet) {
data->joliet = 1; copy_voldesc = 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

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

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

@ -41,6 +41,7 @@ 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_suppress_esc = 0;
int g_ventoy_menu_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. */
@ -802,39 +803,53 @@ 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:
cmdstr = grub_env_get("VTOY_F2_CMD"); if (0 == g_ventoy_fn_mutex) {
if (cmdstr) cmdstr = grub_env_get("VTOY_F2_CMD");
{ if (cmdstr)
menu_fini (); {
grub_script_execute_sourcecode(cmdstr); menu_fini ();
goto refresh; g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
} }
break; break;
case GRUB_TERM_KEY_F3: case GRUB_TERM_KEY_F3:
cmdstr = grub_env_get("VTOY_F3_CMD"); if (0 == g_ventoy_fn_mutex) {
if (cmdstr) cmdstr = grub_env_get("VTOY_F3_CMD");
{ if (cmdstr)
menu_fini (); {
grub_script_execute_sourcecode(cmdstr); menu_fini ();
goto refresh; grub_script_execute_sourcecode(cmdstr);
goto refresh;
}
} }
break; break;
case GRUB_TERM_KEY_F4: case GRUB_TERM_KEY_F4:
cmdstr = grub_env_get("VTOY_F4_CMD"); if (0 == g_ventoy_fn_mutex) {
if (cmdstr) cmdstr = grub_env_get("VTOY_F4_CMD");
{ if (cmdstr)
menu_fini (); {
grub_script_execute_sourcecode(cmdstr); menu_fini ();
goto refresh; g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
} }
break; break;
case GRUB_TERM_KEY_F5: case GRUB_TERM_KEY_F5:
cmdstr = grub_env_get("VTOY_F5_CMD"); if (0 == g_ventoy_fn_mutex) {
if (cmdstr) cmdstr = grub_env_get("VTOY_F5_CMD");
{ if (cmdstr)
menu_fini (); {
grub_script_execute_sourcecode(cmdstr); menu_fini ();
goto refresh; g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
} }
break; break;
case GRUB_TERM_KEY_F6: case GRUB_TERM_KEY_F6:

View file

@ -68,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;
@ -433,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;
@ -853,6 +875,8 @@ 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);
} }
} }
@ -1031,7 +1055,8 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
" %s_%s \n" " %s_%s \n"
"}\n", "}\n",
grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
img->unsupport ? "[unsupported] " : "", img->name, img->id, img->unsupport ? "[unsupported] " : "",
img->alias ? img->alias : img->name, img->id,
(img->type == img_type_iso) ? "iso" : "wim", (img->type == img_type_iso) ? "iso" : "wim",
img->unsupport ? "unsupport_menuentry" : "common_menuentry"); img->unsupport ? "unsupport_menuentry" : "common_menuentry");
} }
@ -1115,7 +1140,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
if (strdata && strdata[0] == '/') if (strdata && strdata[0] == '/')
{ {
len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata);
if (g_img_iterator_head.dir[len] != '/') if (g_img_iterator_head.dir[len - 1] != '/')
{ {
g_img_iterator_head.dir[len++] = '/'; g_img_iterator_head.dir[len++] = '/';
} }
@ -1174,7 +1199,8 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
"menuentry \"%s%s\" --id=\"VID_%d\" {\n" "menuentry \"%s%s\" --id=\"VID_%d\" {\n"
" %s_%s \n" " %s_%s \n"
"}\n", "}\n",
cur->unsupport ? "[unsupported] " : "", cur->name, cur->id, cur->unsupport ? "[unsupported] " : "",
cur->alias ? cur->alias : cur->name, cur->id,
(cur->type == img_type_iso) ? "iso" : "wim", (cur->type == img_type_iso) ? "iso" : "wim",
cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
} }
@ -1394,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;
@ -1419,6 +1446,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++)
@ -1567,6 +1602,8 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
(void)argc; (void)argc;
(void)args; (void)args;
debug("select auto installation %d\n", argc);
if (argc < 1) if (argc < 1)
{ {
return 0; return 0;
@ -1575,6 +1612,7 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
node = ventoy_plugin_find_install_template(args[0]); node = ventoy_plugin_find_install_template(args[0]);
if (!node) if (!node)
{ {
debug("Install template not found for %s\n", args[0]);
return 0; return 0;
} }
@ -1622,6 +1660,8 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
(void)argc; (void)argc;
(void)args; (void)args;
debug("select persistece %d\n", argc);
if (argc < 1) if (argc < 1)
{ {
return 0; return 0;
@ -1630,6 +1670,7 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
node = ventoy_plugin_find_persistent(args[0]); node = ventoy_plugin_find_persistent(args[0]);
if (!node) if (!node)
{ {
debug("Persistence image not found for %s\n", args[0]);
return 0; return 0;
} }
@ -1854,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;
@ -1962,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;
@ -2109,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);
@ -2146,11 +2253,13 @@ static cmd_para ventoy_cmds[] =
{ "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_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
{ "vt_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 },
@ -2164,18 +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_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

@ -132,6 +132,9 @@ 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; int type;
grub_uint64_t size; grub_uint64_t size;
@ -363,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
@ -412,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;
@ -440,9 +458,9 @@ 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_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
( (
@ -596,12 +614,23 @@ typedef struct persistence_config
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_menu_esc;
extern int g_ventoy_suppress_esc; extern int g_ventoy_suppress_esc;
extern int g_ventoy_last_entry; extern int g_ventoy_last_entry;
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);
@ -611,9 +640,15 @@ 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, int index, ventoy_img_chunk_list *chunk_list); int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list);
const char * ventoy_plugin_get_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

@ -841,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;
@ -1100,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,6 +230,92 @@ 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 static int ventoy_plugin_parse_fullpath
( (
VTOY_JSON *json, VTOY_JSON *json,
@ -209,6 +400,46 @@ static int ventoy_plugin_parse_fullpath
return rc; 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; int pathnum = 0;
@ -264,6 +495,45 @@ 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)
{ {
@ -322,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)
@ -566,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;
}

View file

@ -40,13 +40,229 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
wim_hash g_old_hash; static int g_iso_fs_type = 0;
wim_tail g_wim_data; static int g_wim_total_patch_count = 0;
static int g_wim_valid_patch_count = 0;
static wim_patch *g_wim_patch_head = NULL;
static wim_lookup_entry *g_replace_look = NULL; grub_uint8_t g_temp_buf[512];
grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf ); grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf );
static wim_patch *ventoy_find_wim_patch(const char *path)
{
int len = (int)grub_strlen(path);
wim_patch *node = g_wim_patch_head;
while (node)
{
if (len == node->pathlen && 0 == grub_strcmp(path, node->path))
{
return node;
}
node = node->next;
}
return NULL;
}
static int ventoy_collect_wim_patch(const char *bcdfile)
{
int i, j, k;
int rc = 1;
grub_uint64_t magic;
grub_file_t file = NULL;
char *buf = NULL;
wim_patch *node = NULL;
char c;
grub_uint8_t byte;
char valid;
char path[256];
g_ventoy_case_insensitive = 1;
file = grub_file_open(bcdfile, VENTOY_FILE_TYPE);
g_ventoy_case_insensitive = 0;
if (!file)
{
debug("Failed to open file %s\n", bcdfile);
grub_errno = 0;
goto end;
}
buf = grub_malloc(file->size + 8);
if (!buf)
{
goto end;
}
grub_file_read(file, buf, file->size);
for (i = 0; i < (int)file->size - 8; i++)
{
if (buf[i + 8] != 0)
{
continue;
}
magic = *(grub_uint64_t *)(buf + i);
/* .wim .WIM .Wim */
if ((magic == 0x006D00690077002EULL) ||
(magic == 0x004D00490057002EULL) ||
(magic == 0x006D00690057002EULL))
{
for (j = i; j > 0; j-= 2)
{
if (*(grub_uint16_t *)(buf + j) == 0)
{
break;
}
}
if (j > 0)
{
byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j + 2));
if (byte != '/' && byte != '\\')
{
continue;
}
valid = 1;
for (k = 0, j += 2; k < (int)sizeof(path) - 1 && j < i + 8; j += 2)
{
byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j));
c = (char)byte;
if (byte > '~' || byte < ' ') /* not printable */
{
valid = 0;
break;
}
else if (c == '\\')
{
c = '/';
}
path[k++] = c;
}
path[k++] = 0;
debug("@@@@ Find wim flag:<%s>\n", path);
if (0 == valid)
{
debug("Invalid wim file %d\n", k);
}
else if (NULL == ventoy_find_wim_patch(path))
{
node = grub_zalloc(sizeof(wim_patch));
if (node)
{
node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", path);
debug("add patch <%s>\n", path);
if (g_wim_patch_head)
{
node->next = g_wim_patch_head;
}
g_wim_patch_head = node;
g_wim_total_patch_count++;
}
}
else
{
debug("wim <%s> already exist\n", path);
}
}
}
}
end:
check_free(file, grub_file_close);
grub_check_free(buf);
return rc;
}
grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args)
{
char buf[32];
(void)ctxt;
(void)argc;
(void)args;
if (argc == 1)
{
grub_snprintf(buf, sizeof(buf), "%d", g_wim_total_patch_count);
ventoy_set_env(args[0], buf);
}
return 0;
}
grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
{
wim_patch *node = NULL;
(void)ctxt;
(void)argc;
(void)args;
if (argc != 2)
{
return 1;
}
debug("ventoy_cmd_collect_wim_patch %s %s\n", args[0], args[1]);
if (grub_strcmp(args[0], "bcd") == 0)
{
ventoy_collect_wim_patch(args[1]);
return 0;
}
if (NULL == ventoy_find_wim_patch(args[1]))
{
node = grub_zalloc(sizeof(wim_patch));
if (node)
{
node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", args[1]);
debug("add patch <%s>\n", args[1]);
if (g_wim_patch_head)
{
node->next = g_wim_patch_head;
}
g_wim_patch_head = node;
g_wim_total_patch_count++;
}
}
return 0;
}
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
wim_patch *node = NULL;
(void)ctxt;
(void)argc;
(void)args;
for (node = g_wim_patch_head; node; node = node->next)
{
grub_printf("%d %s [%s]\n", i++, node->path, node->valid ? "SUCCESS" : "FAIL");
}
return 0;
}
static int wim_name_cmp(const char *search, grub_uint16_t *name, grub_uint16_t namelen) static int wim_name_cmp(const char *search, grub_uint16_t *name, grub_uint16_t namelen)
{ {
char c1 = vtoy_to_upper(*search); char c1 = vtoy_to_upper(*search);
@ -96,16 +312,24 @@ static int ventoy_is_pe64(grub_uint8_t *buffer)
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)
{ {
wim_patch *next = NULL;
wim_patch *node = g_wim_patch_head;
(void)ctxt; (void)ctxt;
(void)argc; (void)argc;
(void)args; (void)args;
while (node)
{
next = node->next;
grub_free(node);
node = next;
}
g_wim_patch_head = NULL;
g_wim_total_patch_count = 0;
g_wim_valid_patch_count = 0;
check_free(g_wim_data.jump_bin_data, grub_free);
check_free(g_wim_data.new_meta_data, grub_free);
check_free(g_wim_data.new_lookup_data, grub_free);
grub_memset(&g_wim_data, 0, sizeof(g_wim_data));
return 0; return 0;
} }
@ -159,7 +383,7 @@ end:
return 0; return 0;
} }
static int ventoy_get_override_info(grub_file_t file) static int ventoy_get_override_info(grub_file_t file, wim_tail *wim_data)
{ {
grub_uint32_t start_block; grub_uint32_t start_block;
grub_uint64_t file_offset; grub_uint64_t file_offset;
@ -169,7 +393,7 @@ static int ventoy_get_override_info(grub_file_t file)
if (grub_strcmp(file->fs->name, "iso9660") == 0) if (grub_strcmp(file->fs->name, "iso9660") == 0)
{ {
g_wim_data.iso_type = 0; g_iso_fs_type = wim_data->iso_type = 0;
override_len = sizeof(ventoy_iso9660_override); override_len = sizeof(ventoy_iso9660_override);
override_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2; override_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2;
@ -181,7 +405,7 @@ static int ventoy_get_override_info(grub_file_t file)
} }
else else
{ {
g_wim_data.iso_type = 1; g_iso_fs_type = wim_data->iso_type = 1;
override_len = sizeof(ventoy_udf_override); override_len = sizeof(ventoy_udf_override);
override_offset = grub_udf_get_last_file_attr_offset(file, &start_block, &fe_entry_size_offset); override_offset = grub_udf_get_last_file_attr_offset(file, &start_block, &fe_entry_size_offset);
@ -191,11 +415,11 @@ static int ventoy_get_override_info(grub_file_t file)
(ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block); (ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block);
} }
g_wim_data.file_offset = file_offset; wim_data->file_offset = file_offset;
g_wim_data.udf_start_block = start_block; wim_data->udf_start_block = start_block;
g_wim_data.fe_entry_size_offset = fe_entry_size_offset; wim_data->fe_entry_size_offset = fe_entry_size_offset;
g_wim_data.override_offset = override_offset; wim_data->override_offset = override_offset;
g_wim_data.override_len = override_len; wim_data->override_len = override_len;
return 0; return 0;
} }
@ -336,7 +560,7 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire
{ {
wim_directory_entry *wim_dirent = NULL; wim_directory_entry *wim_dirent = NULL;
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL }; const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL }; //const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL };
wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path); wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path);
if (wim_dirent) if (wim_dirent)
@ -344,11 +568,13 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire
return wim_dirent; return wim_dirent;
} }
#if 0
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path); wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
if (wim_dirent) if (wim_dirent)
{ {
return wim_dirent; return wim_dirent;
} }
#endif
return NULL; return NULL;
} }
@ -394,7 +620,7 @@ static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_
return NULL; return NULL;
} }
static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir) static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir)
{ {
if ((meta_data == NULL) || (dir == NULL)) if ((meta_data == NULL) || (dir == NULL))
{ {
@ -408,15 +634,15 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir)
do do
{ {
if (dir->subdir == 0 && grub_memcmp(dir->hash.sha1, g_old_hash.sha1, sizeof(wim_hash)) == 0) if (dir->subdir == 0 && grub_memcmp(dir->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0)
{ {
debug("find target file, name_len:%u upadte hash\n", dir->name_len); debug("find target file, name_len:%u upadte hash\n", dir->name_len);
grub_memcpy(dir->hash.sha1, &(g_wim_data.bin_hash), sizeof(wim_hash)); grub_memcpy(dir->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash));
} }
if (dir->subdir) if (dir->subdir)
{ {
ventoy_update_all_hash(meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir)); ventoy_update_all_hash(patch, meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir));
} }
dir = (wim_directory_entry *)((char *)dir + dir->len); dir = (wim_directory_entry *)((char *)dir + dir->len);
@ -425,7 +651,7 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir)
return 0; return 0;
} }
static int ventoy_cat_exe_file_data(grub_uint32_t exe_len, grub_uint8_t *exe_data) static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, grub_uint8_t *exe_data)
{ {
int pe64 = 0; int pe64 = 0;
char file[256]; char file[256];
@ -439,19 +665,19 @@ static int ventoy_cat_exe_file_data(grub_uint32_t exe_len, grub_uint8_t *exe_dat
ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL); ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL);
jump_align = ventoy_align(jump_len, 16); jump_align = ventoy_align(jump_len, 16);
g_wim_data.jump_exe_len = jump_len; wim_data->jump_exe_len = jump_len;
g_wim_data.bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len; wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len;
g_wim_data.bin_align_len = ventoy_align(g_wim_data.bin_raw_len, 2048); wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048);
g_wim_data.jump_bin_data = grub_malloc(g_wim_data.bin_align_len); wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len);
if (g_wim_data.jump_bin_data) if (wim_data->jump_bin_data)
{ {
grub_memcpy(g_wim_data.jump_bin_data, jump_data, jump_len); grub_memcpy(wim_data->jump_bin_data, jump_data, jump_len);
grub_memcpy(g_wim_data.jump_bin_data + jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data), exe_data, exe_len); grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data), exe_data, exe_len);
} }
debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n", debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n",
g_wim_data.jump_exe_len, g_wim_data.bin_raw_len, g_wim_data.bin_align_len); wim_data->jump_exe_len, wim_data->bin_raw_len, wim_data->bin_align_len);
return 0; return 0;
} }
@ -490,49 +716,63 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath)
wim_lookup_entry *meta_look = NULL; wim_lookup_entry *meta_look = NULL;
wim_security_header *security = NULL; wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL; wim_directory_entry *rootdir = NULL;
wim_header *head = &(g_wim_data.wim_header); wim_header *head = NULL;
wim_lookup_entry *lookup = (wim_lookup_entry *)g_wim_data.new_lookup_data; wim_lookup_entry *lookup = NULL;
wim_patch *node = NULL;
wim_tail *wim_data = NULL;
jump_align = ventoy_align(g_wim_data.jump_exe_len, 16); for (node = g_wim_patch_head; node; node = node->next)
if (g_wim_data.jump_bin_data)
{ {
grub_memcpy(g_wim_data.jump_bin_data + jump_align, param, sizeof(ventoy_os_param)); if (0 == node->valid)
ventoy_fill_windows_rtdata(g_wim_data.jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath); {
} continue;
}
grub_crypto_hash(GRUB_MD_SHA1, g_wim_data.bin_hash.sha1, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len); wim_data = &node->wim_data;
head = &wim_data->wim_header;
lookup = (wim_lookup_entry *)wim_data->new_lookup_data;
security = (wim_security_header *)g_wim_data.new_meta_data; jump_align = ventoy_align(wim_data->jump_exe_len, 16);
rootdir = (wim_directory_entry *)(g_wim_data.new_meta_data + ((security->len + 7) & 0xFFFFFFF8U)); if (wim_data->jump_bin_data)
{
grub_memcpy(wim_data->jump_bin_data + jump_align, param, sizeof(ventoy_os_param));
ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath);
}
/* update all winpeshl.exe dirent entry's hash */ grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len);
ventoy_update_all_hash(g_wim_data.new_meta_data, rootdir);
/* update winpeshl.exe lookup entry data (hash/offset/length) */ security = (wim_security_header *)wim_data->new_meta_data;
if (g_replace_look) rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U));
{
debug("update replace lookup entry_id:%ld\n", ((long)g_replace_look - (long)lookup) / sizeof(wim_lookup_entry));
g_replace_look->resource.raw_size = g_wim_data.bin_raw_len;
g_replace_look->resource.size_in_wim = g_wim_data.bin_raw_len;
g_replace_look->resource.flags = 0;
g_replace_look->resource.offset = g_wim_data.wim_align_size;
grub_memcpy(g_replace_look->hash.sha1, g_wim_data.bin_hash.sha1, sizeof(wim_hash)); /* update all winpeshl.exe dirent entry's hash */
} ventoy_update_all_hash(node, wim_data->new_meta_data, rootdir);
/* update metadata's hash */ /* update winpeshl.exe lookup entry data (hash/offset/length) */
meta_look = ventoy_find_meta_entry(head, lookup); if (node->replace_look)
if (meta_look) {
{ debug("update replace lookup entry_id:%ld\n", ((long)node->replace_look - (long)lookup) / sizeof(wim_lookup_entry));
debug("find meta lookup entry_id:%ld\n", ((long)meta_look - (long)lookup) / sizeof(wim_lookup_entry)); node->replace_look->resource.raw_size = wim_data->bin_raw_len;
grub_memcpy(&meta_look->resource, &head->metadata, sizeof(wim_resource_header)); node->replace_look->resource.size_in_wim = wim_data->bin_raw_len;
grub_crypto_hash(GRUB_MD_SHA1, meta_look->hash.sha1, g_wim_data.new_meta_data, g_wim_data.new_meta_len); node->replace_look->resource.flags = 0;
node->replace_look->resource.offset = wim_data->wim_align_size;
grub_memcpy(node->replace_look->hash.sha1, wim_data->bin_hash.sha1, sizeof(wim_hash));
}
/* update metadata's hash */
meta_look = ventoy_find_meta_entry(head, lookup);
if (meta_look)
{
debug("find meta lookup entry_id:%ld\n", ((long)meta_look - (long)lookup) / sizeof(wim_lookup_entry));
grub_memcpy(&meta_look->resource, &head->metadata, sizeof(wim_resource_header));
grub_crypto_hash(GRUB_MD_SHA1, meta_look->hash.sha1, wim_data->new_meta_data, wim_data->new_meta_len);
}
} }
return 0; return 0;
} }
grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, char **args) static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
{ {
int rc; int rc;
grub_file_t file; grub_file_t file;
@ -543,20 +783,22 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
wim_security_header *security = NULL; wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL; wim_directory_entry *rootdir = NULL;
wim_directory_entry *search = NULL; wim_directory_entry *search = NULL;
wim_header *head = &(g_wim_data.wim_header); wim_header *head = &(patch->wim_data.wim_header);
wim_tail *wim_data = &patch->wim_data;
(void)ctxt; debug("windows locate wim start %s\n", patch->path);
(void)argc;
debug("windows locate wim start %s\n", args[0]); g_ventoy_case_insensitive = 1;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", disk, patch->path);
g_ventoy_case_insensitive = 0;
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
if (!file) if (!file)
{ {
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); debug("File %s%s NOT exist\n", disk, patch->path);
return 1;
} }
ventoy_get_override_info(file); ventoy_get_override_info(file, &patch->wim_data);
grub_file_seek(file, 0); grub_file_seek(file, 0);
grub_file_read(file, head, sizeof(wim_header)); grub_file_read(file, head, sizeof(wim_header));
@ -596,8 +838,8 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
} }
debug("find replace file at %p\n", search); debug("find replace file at %p\n", search);
grub_memcpy(&g_old_hash, search->hash.sha1, sizeof(wim_hash)); grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash));
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size); debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
lookup = grub_malloc(head->lookup.raw_size); lookup = grub_malloc(head->lookup.raw_size);
@ -605,16 +847,16 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
grub_file_read(file, lookup, head->lookup.raw_size); grub_file_read(file, lookup, head->lookup.raw_size);
/* find and extact winpeshl.exe */ /* find and extact winpeshl.exe */
g_replace_look = ventoy_find_look_entry(head, lookup, &g_old_hash); patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash);
if (g_replace_look) if (patch->replace_look)
{ {
exe_len = (grub_uint32_t)g_replace_look->resource.raw_size; exe_len = (grub_uint32_t)patch->replace_look->resource.raw_size;
debug("find replace lookup entry_id:%ld raw_size:%u\n", debug("find replace lookup entry_id:%ld raw_size:%u\n",
((long)g_replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len); ((long)patch->replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len);
if (0 == ventoy_read_resource(file, &(g_replace_look->resource), (void **)&(exe_data))) if (0 == ventoy_read_resource(file, &(patch->replace_look->resource), (void **)&(exe_data)))
{ {
ventoy_cat_exe_file_data(exe_len, exe_data); ventoy_cat_exe_file_data(wim_data, exe_len, exe_data);
grub_free(exe_data); grub_free(exe_data);
} }
else else
@ -624,106 +866,236 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
} }
else else
{ {
debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n", g_old_hash.sha1[0], g_old_hash.sha1[1]); debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n",
patch->old_hash.sha1[0], patch->old_hash.sha1[1]);
} }
g_wim_data.wim_raw_size = (grub_uint32_t)file->size; wim_data->wim_raw_size = (grub_uint32_t)file->size;
g_wim_data.wim_align_size = ventoy_align(g_wim_data.wim_raw_size, 2048); wim_data->wim_align_size = ventoy_align(wim_data->wim_raw_size, 2048);
check_free(g_wim_data.new_meta_data, grub_free); grub_check_free(wim_data->new_meta_data);
g_wim_data.new_meta_data = decompress_data; wim_data->new_meta_data = decompress_data;
g_wim_data.new_meta_len = head->metadata.raw_size; wim_data->new_meta_len = head->metadata.raw_size;
g_wim_data.new_meta_align_len = ventoy_align(g_wim_data.new_meta_len, 2048); wim_data->new_meta_align_len = ventoy_align(wim_data->new_meta_len, 2048);
check_free(g_wim_data.new_lookup_data, grub_free); grub_check_free(wim_data->new_lookup_data);
g_wim_data.new_lookup_data = (grub_uint8_t *)lookup; wim_data->new_lookup_data = (grub_uint8_t *)lookup;
g_wim_data.new_lookup_len = (grub_uint32_t)head->lookup.raw_size; wim_data->new_lookup_len = (grub_uint32_t)head->lookup.raw_size;
g_wim_data.new_lookup_align_len = ventoy_align(g_wim_data.new_lookup_len, 2048); wim_data->new_lookup_align_len = ventoy_align(wim_data->new_lookup_len, 2048);
head->metadata.flags = RESHDR_FLAG_METADATA; head->metadata.flags = RESHDR_FLAG_METADATA;
head->metadata.offset = g_wim_data.wim_align_size + g_wim_data.bin_align_len; head->metadata.offset = wim_data->wim_align_size + wim_data->bin_align_len;
head->metadata.size_in_wim = g_wim_data.new_meta_len; head->metadata.size_in_wim = wim_data->new_meta_len;
head->metadata.raw_size = g_wim_data.new_meta_len; head->metadata.raw_size = wim_data->new_meta_len;
head->lookup.flags = 0; head->lookup.flags = 0;
head->lookup.offset = head->metadata.offset + g_wim_data.new_meta_align_len; head->lookup.offset = head->metadata.offset + wim_data->new_meta_align_len;
head->lookup.size_in_wim = g_wim_data.new_lookup_len; head->lookup.size_in_wim = wim_data->new_lookup_len;
head->lookup.raw_size = g_wim_data.new_lookup_len; head->lookup.raw_size = wim_data->new_lookup_len;
grub_file_close(file); grub_file_close(file);
debug("%s", "windows locate wim finish\n"); debug("%s", "windows locate wim finish\n");
VENTOY_CMD_RETURN(GRUB_ERR_NONE); return 0;
}
grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
{
wim_patch *node = g_wim_patch_head;
(void)ctxt;
(void)argc;
(void)args;
while (node)
{
if (0 == ventoy_wimdows_locate_wim(args[0], node))
{
node->valid = 1;
g_wim_valid_patch_count++;
}
node = node->next;
}
return 0;
} }
static grub_uint32_t ventoy_get_override_chunk_num(void) static grub_uint32_t ventoy_get_override_chunk_num(void)
{ {
/* 1: block count in Partition Descriptor */ if (g_iso_fs_type == 0)
/* 2: file_size in file_entry or extend_file_entry */ {
/* 3: data_size and position in extend data short ad */ /* ISO9660: */
/* 4: new wim file header */ /* per wim */
return 4; /* 1: file_size and file_offset */
/* 2: new wim file header */
return g_wim_valid_patch_count * 2;
}
else
{
/* UDF: */
/* global: */
/* 1: block count in Partition Descriptor */
/* per wim */
/* 1: file_size in file_entry or extend_file_entry */
/* 2: data_size and position in extend data short ad */
/* 3: new wim file header */
return g_wim_valid_patch_count * 3 + 1;
}
} }
static void ventoy_windows_fill_override_data( grub_uint64_t isosize, void *override) static void ventoy_windows_fill_override_data_iso9660( grub_uint64_t isosize, void *override)
{ {
grub_uint32_t data32;
grub_uint64_t data64;
grub_uint64_t sector; grub_uint64_t sector;
grub_uint32_t new_wim_size; grub_uint32_t new_wim_size;
ventoy_override_chunk *cur; ventoy_override_chunk *cur;
wim_patch *node = NULL;
wim_tail *wim_data = NULL;
ventoy_iso9660_override *dirent = NULL;
sector = (isosize + 2047) / 2048; sector = (isosize + 2047) / 2048;
cur = (ventoy_override_chunk *)override; cur = (ventoy_override_chunk *)override;
new_wim_size = g_wim_data.wim_align_size + g_wim_data.bin_align_len + debug("ventoy_windows_fill_override_data_iso9660 %lu\n", (ulong)isosize);
g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len;
if (g_wim_data.iso_type == 0) for (node = g_wim_patch_head; node; node = node->next)
{ {
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)g_wim_data.override_data; wim_data = &node->wim_data;
if (0 == node->valid)
{
continue;
}
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
dirent = (ventoy_iso9660_override *)wim_data->override_data;
dirent->first_sector = (grub_uint32_t)sector; dirent->first_sector = (grub_uint32_t)sector;
dirent->size = new_wim_size; dirent->size = new_wim_size;
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);
sector += (new_wim_size / 2048);
/* override 1: position and length in dirent */
cur->img_offset = wim_data->override_offset;
cur->override_size = wim_data->override_len;
grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size);
cur++;
/* override 2: new wim file header */
cur->img_offset = wim_data->file_offset;
cur->override_size = sizeof(wim_header);
grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size);
cur++;
} }
else
return;
}
static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, void *override)
{
grub_uint32_t data32;
grub_uint64_t data64;
grub_uint64_t sector;
grub_uint32_t new_wim_size;
grub_uint64_t total_wim_size = 0;
grub_uint32_t udf_start_block = 0;
ventoy_override_chunk *cur;
wim_patch *node = NULL;
wim_tail *wim_data = NULL;
ventoy_udf_override *udf = NULL;
sector = (isosize + 2047) / 2048;
cur = (ventoy_override_chunk *)override;
debug("ventoy_windows_fill_override_data_udf %lu\n", (ulong)isosize);
for (node = g_wim_patch_head; node; node = node->next)
{ {
ventoy_udf_override *udf = (ventoy_udf_override *)g_wim_data.override_data; wim_data = &node->wim_data;
udf->length = new_wim_size; if (node->valid)
udf->position = (grub_uint32_t)sector - g_wim_data.udf_start_block; {
if (udf_start_block == 0)
{
udf_start_block = wim_data->udf_start_block;
}
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
total_wim_size += new_wim_size;
}
} }
//override 1: sector number in pd data //override 1: sector number in pd data
cur->img_offset = grub_udf_get_last_pd_size_offset(); cur->img_offset = grub_udf_get_last_pd_size_offset();
cur->override_size = 4; cur->override_size = 4;
data32 = sector - g_wim_data.udf_start_block + (new_wim_size / 2048); data32 = sector - udf_start_block + (total_wim_size / 2048);
grub_memcpy(cur->override_data, &(data32), 4); grub_memcpy(cur->override_data, &(data32), 4);
//override 2: filesize in file_entry for (node = g_wim_patch_head; node; node = node->next)
cur++; {
cur->img_offset = g_wim_data.fe_entry_size_offset; wim_data = &node->wim_data;
cur->override_size = 8; if (0 == node->valid)
data64 = new_wim_size; {
grub_memcpy(cur->override_data, &(data64), 8); continue;
}
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
/* override 3: position and length in extend data */ //override 2: filesize in file_entry
cur++; cur++;
cur->img_offset = g_wim_data.override_offset; cur->img_offset = wim_data->fe_entry_size_offset;
cur->override_size = g_wim_data.override_len; cur->override_size = 8;
grub_memcpy(cur->override_data, g_wim_data.override_data, cur->override_size); data64 = new_wim_size;
grub_memcpy(cur->override_data, &(data64), 8);
/* override 4: new wim file header */ udf = (ventoy_udf_override *)wim_data->override_data;
cur++; udf->length = new_wim_size;
cur->img_offset = g_wim_data.file_offset; udf->position = (grub_uint32_t)sector - udf_start_block;
cur->override_size = sizeof(wim_header);
grub_memcpy(cur->override_data, &(g_wim_data.wim_header), cur->override_size); sector += (new_wim_size / 2048);
/* override 3: position and length in extend data */
cur++;
cur->img_offset = wim_data->override_offset;
cur->override_size = wim_data->override_len;
grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size);
/* override 4: new wim file header */
cur++;
cur->img_offset = wim_data->file_offset;
cur->override_size = sizeof(wim_header);
grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size);
}
return; return;
} }
static grub_uint32_t ventoy_windows_get_virt_data_size(void)
{
grub_uint32_t size = 0;
wim_tail *wim_data = NULL;
wim_patch *node = g_wim_patch_head;
while (node)
{
if (node->valid)
{
wim_data = &node->wim_data;
size += sizeof(ventoy_virt_chunk) + wim_data->bin_align_len +
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
}
node = node->next;
}
return size;
}
static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
{ {
grub_uint64_t sector; grub_uint64_t sector;
@ -732,37 +1104,53 @@ static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chai
grub_uint32_t mem_secs; grub_uint32_t mem_secs;
char *override = NULL; char *override = NULL;
ventoy_virt_chunk *cur = NULL; ventoy_virt_chunk *cur = NULL;
wim_tail *wim_data = NULL;
wim_patch *node = NULL;
sector = (isosize + 2047) / 2048; sector = (isosize + 2047) / 2048;
offset = sizeof(ventoy_virt_chunk); offset = sizeof(ventoy_virt_chunk) * g_wim_valid_patch_count;
wim_secs = g_wim_data.wim_align_size / 2048;
mem_secs = (g_wim_data.bin_align_len + g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len) / 2048;
override = (char *)chain + chain->virt_chunk_offset; override = (char *)chain + chain->virt_chunk_offset;
cur = (ventoy_virt_chunk *)override; cur = (ventoy_virt_chunk *)override;
cur->remap_sector_start = sector; for (node = g_wim_patch_head; node; node = node->next)
cur->remap_sector_end = cur->remap_sector_start + wim_secs; {
cur->org_sector_start = (grub_uint32_t)(g_wim_data.file_offset / 2048); if (0 == node->valid)
{
cur->mem_sector_start = cur->remap_sector_end; continue;
cur->mem_sector_end = cur->mem_sector_start + mem_secs; }
cur->mem_sector_offset = offset;
grub_memcpy(override + offset, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len); wim_data = &node->wim_data;
offset += g_wim_data.bin_align_len;
grub_memcpy(override + offset, g_wim_data.new_meta_data, g_wim_data.new_meta_len); wim_secs = wim_data->wim_align_size / 2048;
offset += g_wim_data.new_meta_align_len; mem_secs = (wim_data->bin_align_len + wim_data->new_meta_align_len + wim_data->new_lookup_align_len) / 2048;
grub_memcpy(override + offset, g_wim_data.new_lookup_data, g_wim_data.new_lookup_len); cur->remap_sector_start = sector;
offset += g_wim_data.new_lookup_align_len; cur->remap_sector_end = cur->remap_sector_start + wim_secs;
cur->org_sector_start = (grub_uint32_t)(wim_data->file_offset / 2048);
cur->mem_sector_start = cur->remap_sector_end;
cur->mem_sector_end = cur->mem_sector_start + mem_secs;
cur->mem_sector_offset = offset;
sector += wim_secs + mem_secs;
cur++;
grub_memcpy(override + offset, wim_data->jump_bin_data, wim_data->bin_raw_len);
offset += wim_data->bin_align_len;
grub_memcpy(override + offset, wim_data->new_meta_data, wim_data->new_meta_len);
offset += wim_data->new_meta_align_len;
grub_memcpy(override + offset, wim_data->new_lookup_data, wim_data->new_lookup_len);
offset += wim_data->new_lookup_align_len;
chain->virt_img_size_in_bytes += wim_data->wim_align_size +
wim_data->bin_align_len +
wim_data->new_meta_align_len +
wim_data->new_lookup_align_len;
}
chain->virt_img_size_in_bytes += g_wim_data.wim_align_size +
g_wim_data.bin_align_len +
g_wim_data.new_meta_align_len +
g_wim_data.new_lookup_align_len;
return; return;
} }
@ -828,7 +1216,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
return 1; return 1;
} }
if (0 == ventoy_compatible && g_wim_data.new_meta_data == NULL) if (0 == ventoy_compatible && g_wim_valid_patch_count == 0)
{ {
unknown_image = 1; unknown_image = 1;
debug("Warning: %s was not recognized by Ventoy\n", args[0]); debug("Warning: %s was not recognized by Ventoy\n", args[0]);
@ -871,8 +1259,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
else else
{ {
override_size = ventoy_get_override_chunk_num() * sizeof(ventoy_override_chunk); override_size = ventoy_get_override_chunk_num() * sizeof(ventoy_override_chunk);
virt_chunk_size = sizeof(ventoy_virt_chunk) + g_wim_data.bin_align_len + virt_chunk_size = ventoy_windows_get_virt_data_size();
g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len;;
size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size; size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size;
} }
@ -903,9 +1290,10 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
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 = 1;
ventoy_fill_os_param(file, &(chain->os_param)); ventoy_fill_os_param(file, &(chain->os_param));
if (g_wim_data.jump_bin_data && g_wim_data.new_meta_data) if (0 == unknown_image)
{ {
ventoy_update_before_chain(&(chain->os_param), args[0]); ventoy_update_before_chain(&(chain->os_param), args[0]);
} }
@ -934,7 +1322,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
return 0; return 0;
} }
if (g_wim_data.new_meta_data == NULL) if (0 == g_wim_valid_patch_count)
{ {
return 0; return 0;
} }
@ -942,11 +1330,19 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
/* part 4: override chunk */ /* part 4: override chunk */
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
chain->override_chunk_num = ventoy_get_override_chunk_num(); chain->override_chunk_num = ventoy_get_override_chunk_num();
ventoy_windows_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
if (g_iso_fs_type == 0)
{
ventoy_windows_fill_override_data_iso9660(isosize, (char *)chain + chain->override_chunk_offset);
}
else
{
ventoy_windows_fill_override_data_udf(isosize, (char *)chain + chain->override_chunk_offset);
}
/* part 5: virt chunk */ /* part 5: virt chunk */
chain->virt_chunk_offset = chain->override_chunk_offset + override_size; chain->virt_chunk_offset = chain->override_chunk_offset + override_size;
chain->virt_chunk_num = 1; chain->virt_chunk_num = g_wim_valid_patch_count;
ventoy_windows_fill_virt_data(isosize, chain); ventoy_windows_fill_virt_data(isosize, chain);
if (ventoy_is_efi_os() == 0) if (ventoy_is_efi_os() == 0)
@ -1099,6 +1495,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
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

@ -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 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" 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,4 +19,10 @@
. $VTOY_PATH/hook/ventoy-os-lib.sh . $VTOY_PATH/hook/ventoy-os-lib.sh
$SED "/find_and_mount_installer *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init 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
else
echo "find_installer" >> $VTLOG
$SED "/\$.*find_installer/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/clear/disk-hook.sh" -i /init
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 ] || [ -d /lib/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 else
if $GREP -q kaspersky /proc/version; then $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
$SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
else
$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

@ -19,22 +19,13 @@
. /ventoy/hook/ventoy-hook-lib.sh . /ventoy/hook/ventoy-hook-lib.sh
if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt)
exit 0
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 fi
ventoy_udev_disk_common_hook $*
#
# 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
# OK finish
set_ventoy_hook_finish

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,7 +31,13 @@ else
VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs" VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs"
break break
fi fi
done
if echo $vtParam | $GREP -q '^ks=.*:/'; then
vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}')
VTKS="ks=hd:/dev/dm-0:$vtRawKs"
break
fi
done
fi fi
echo "VTKS=$VTKS" >> $VTLOG echo "VTKS=$VTKS" >> $VTLOG
@ -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,9 +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
vtlog "set anaconda-diskroot ..." if [ -e /sbin/anaconda-diskroot ]; then
/sbin/anaconda-diskroot /dev/dm-0 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,8 +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/anaconda-diskroot /dev/dm-0 vtlog "set anaconda-diskroot ..."
#/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/$vtDM /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
@ -215,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 #

Binary file not shown.

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,60 +16,91 @@
# #
#************************************************************************************ #************************************************************************************
function ventoy_pause {
if [ -n "${vtdebug_flag}" ]; then
echo "press Enter to continue ......"
read vtTmpPause
fi
}
function ventoy_debug_pause {
if [ -n "${vtdebug_flag}" ]; then
echo "press Enter to continue ......"
read vtTmpPause
fi
}
function ventoy_power { function ventoy_power {
configfile ($root)/grub/power.cfg 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
done done
if [ -n "${vtdebug_flag}" ]; then if [ -n "${vtdebug_flag}" ]; then
echo ISO is $vtoy_os echo ISO is $vtoy_os
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
} }
function locate_initrd { function locate_initrd {
vt_linux_locate_initrd vt_linux_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
@ -127,32 +158,50 @@ function distro_specify_initrd_file_phase2 {
function uefi_windows_menu_func { 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}
ventoy_debug_pause
vt_windows_chain_data ${1}${chosen_path}
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
chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
boot boot
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
@ -166,20 +215,14 @@ function uefi_linux_menu_func {
fi fi
done done
fi fi
# 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
@ -194,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}
@ -204,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
} }
@ -232,6 +293,7 @@ function uefi_iso_menu_func {
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}
@ -257,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}
@ -287,32 +343,50 @@ function uefi_iso_memdisk {
function legacy_windows_menu_func { 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
@ -352,18 +426,15 @@ function legacy_linux_menu_func {
locate_initrd locate_initrd
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
} }
@ -381,12 +452,12 @@ function legacy_iso_menu_func {
set ventoy_fs_probe=udf set ventoy_fs_probe=udf
else else
set ventoy_fs_probe=iso9660 set ventoy_fs_probe=iso9660
fi vt_iso9660_nojoliet 0
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
set ventoy_compatible=YES set ventoy_compatible=YES
unset vtcompat unset vtcompat
@ -399,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}
@ -446,10 +511,9 @@ function iso_unsupport_menuentry {
function wim_common_menuentry { function wim_common_menuentry {
vt_chosen_img_path chosen_path vt_chosen_img_path chosen_path
vt_wim_chain_data ${iso_path}${chosen_path} vt_wim_chain_data ${iso_path}${chosen_path}
if [ -n "${vtdebug_flag}" ]; then
sleep 5 ventoy_debug_pause
fi
if [ -n "$vtoy_chain_mem_addr" ]; then if [ -n "$vtoy_chain_mem_addr" ]; then
if [ "$grub_platform" = "pc" ]; then if [ "$grub_platform" = "pc" ]; then
@ -461,7 +525,7 @@ function wim_common_menuentry {
boot boot
else else
echo "chain empty failed" echo "chain empty failed"
sleep 5 ventoy_pause
fi fi
} }
@ -479,7 +543,7 @@ function wim_unsupport_menuentry {
############################################################# #############################################################
############################################################# #############################################################
set VENTOY_VERSION="1.0.12" 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
@ -490,10 +554,12 @@ set VTOY_DEFAULT_MENU_MODE=0
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"
@ -504,7 +570,7 @@ fi
vt_device $root vtoy_dev vt_device $root vtoy_dev
if [ "$vtoy_dev" = "tftp" ]; then if [ "$vtoy_dev" = "tftp" ]; then
set vtoy_path=($root) set vtoy_path=($root)
for vtid in 0 1 2 3; do for vtid in 0 1 2 3; do
if [ -d (hd$vtid,2)/ventoy ]; then if [ -d (hd$vtid,2)/ventoy ]; then
set iso_path=(hd$vtid,1) set iso_path=(hd$vtid,1)
@ -512,13 +578,19 @@ if [ "$vtoy_dev" = "tftp" ]; then
break break
fi fi
done done
loadfont ascii
else else
set vtoy_path=($root)/ventoy if [ "$prefix" = "(ventoydisk)/grub" ]; then
set vtoy_path=(ventoydisk)/ventoy
else
set vtoy_path=($root)/ventoy
fi
set iso_path=($vtoy_dev,1) set iso_path=($vtoy_dev,1)
set vtoy_efi_part=($vtoy_dev,2) set vtoy_efi_part=($vtoy_dev,2)
loadfont unicode
fi fi
loadfont ascii
#Load Plugin #Load Plugin
if [ -f $iso_path/ventoy/ventoy.json ]; then if [ -f $iso_path/ventoy/ventoy.json ]; then
@ -534,10 +606,10 @@ 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
@ -553,7 +625,13 @@ else
set theme=$prefix/themes/ventoy/theme.txt set theme=$prefix/themes/ventoy/theme.txt
fi fi
terminal_output gfxterm if [ "$vtoy_display_mode" = "CLI" ]; then
terminal_output console
else
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

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 ...'
}

View file

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

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

@ -278,7 +278,7 @@ EOF
echo "create efi fat fs $PART2 ..." 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

@ -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,6 +297,12 @@ 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)
{ {
@ -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

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

View file

@ -492,13 +492,13 @@ 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);
while (Mask) while (Mask)
{ {
if ((Drives & Mask) == 0) if ((Drives & Mask) == 0)
@ -724,7 +724,7 @@ static int ProcessUnattendedInstallation(const char *script)
{ {
Letter = 'X'; Letter = 'X';
} }
sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter); sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter);
Log("Copy file <%s> --> <%s>", script, CurDir); Log("Copy file <%s> --> <%s>", script, CurDir);
CopyFile(script, CurDir, FALSE); CopyFile(script, CurDir, FALSE);