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
#include <Protocol/SimpleFileSystem.h>
#include <Ventoy.h>
-UINTN g_iso_buf_size = 0;
-BOOLEAN gMemdiskMode = FALSE;
BOOLEAN gDebugPrint = FALSE;
-BOOLEAN gLoadIsoEfi = FALSE;
ventoy_ram_disk g_ramdisk_param;
ventoy_chain_head *g_chain;
ventoy_img_chunk *g_chunk;
+UINT8 *g_os_param_reserved;
UINT32 g_img_chunk_num;
ventoy_override_chunk *g_override_chunk;
UINT32 g_override_chunk_num;
ventoy_virt_chunk *g_virt_chunk;
UINT32 g_virt_chunk_num;
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;
-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_efi_file_replace g_efi_file_replace;
CHAR16 gFirstTryBootFile[256] = {0};
-CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
-
/* Boot filename */
UINTN gBootFileStartIndex = 1;
CONST CHAR16 *gEfiBootFileName[] =
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, ...)
{
VA_LIST Marker;
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_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_dump_virt_chunk(chain);
}
-EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath)
+static int ventoy_update_image_location(ventoy_os_param *param)
{
- EFI_HANDLE Handle = NULL;
EFI_STATUS Status = EFI_SUCCESS;
- EFI_DEVICE_PATH_PROTOCOL *pLastNode = NULL;
- EFI_DEVICE_PATH_PROTOCOL *pCurNode = NULL;
- EFI_DEVICE_PATH_PROTOCOL *pTmpDevPath = NULL;
-
- pTmpDevPath = DuplicateDevicePath(pDevPath);
- if (!pTmpDevPath)
- {
- return NULL;
- }
+ 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;
- pCurNode = pTmpDevPath;
- while (!IsDevicePathEnd(pCurNode))
- {
- pLastNode = pCurNode;
- pCurNode = NextDevicePathNode(pCurNode);
- }
- if (pLastNode)
+ 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)
{
- CopyMem(pLastNode, pCurNode, sizeof(EFI_DEVICE_PATH_PROTOCOL));
+ debug("Failed to allocate runtime pool %r\n", Status);
+ return 1;
}
- pCurNode = pTmpDevPath;
- Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pCurNode, &Handle);
- debug("Status:%r Parent Handle:%p DP:%s", Status, Handle, ConvertDevicePathToText(pTmpDevPath, FALSE, FALSE));
-
- FreePool(pTmpDevPath);
-
- 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;
-}
+ address = (UINTN)buffer;
-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 (address % 4096)
{
- 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;
- }
+ address += 4096 - (address % 4096);
}
- if (ReadStart > g_chain->real_img_size_in_bytes)
+ 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++)
{
- return EFI_SUCCESS;
+ chksum += *((UINT8 *)param + i);
}
+ param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum);
- /* override data */
- pCurBuf = (UINT8 *)Buffer;
- for (i = 0; i < g_override_chunk_num; i++, pOverride++)
+ location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr);
+ if (NULL == location)
{
- 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 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);
+ CopyMem(&location->guid, ¶m->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;
- (VOID)This;
- (VOID)MediaId;
+ region = location->regions;
- CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize);
+ 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 EFI_SUCCESS;
+ return 0;
}
-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
-)
+EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath)
{
- 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;
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_DEVICE_PATH_PROTOCOL *pLastNode = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pCurNode = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pTmpDevPath = NULL;
- //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++)
+ pTmpDevPath = DuplicateDevicePath(pDevPath);
+ if (!pTmpDevPath)
{
- 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;
- }
- }
+ return NULL;
}
- for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++)
+ pCurNode = pTmpDevPath;
+ while (!IsDevicePathEnd(pCurNode))
{
- 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;
- }
- }
+ pLastNode = pCurNode;
+ pCurNode = NextDevicePathNode(pCurNode);
}
-
- if (lbacount > 0)
+ if (pLastNode)
{
- ventoy_read_iso_sector(lastlba, lbacount, lastbuffer);
+ CopyMem(pLastNode, pCurNode, sizeof(EFI_DEVICE_PATH_PROTOCOL));
}
- 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;
+ pCurNode = pTmpDevPath;
+ Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pCurNode, &Handle);
+ debug("Status:%r Parent Handle:%p DP:%s", Status, Handle, ConvertDevicePathToText(pTmpDevPath, FALSE, FALSE));
- debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
+ FreePool(pTmpDevPath);
- return EFI_SUCCESS;
+ return Handle;
}
EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
return Status;
}
-EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID)
+EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_GUID VarGuid = VENTOY_GUID;
}
-EFI_STATUS EFIAPI ventoy_set_variable(VOID)
+EFI_STATUS EFIAPI ventoy_save_variable(VOID)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_GUID VarGuid = VENTOY_GUID;
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;
-
- 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
+STATIC EFI_STATUS EFIAPI ventoy_load_image
(
IN EFI_HANDLE ImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath,
}
}
-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, ¶m->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)
{
UINT32 i = 0;
gDebugPrint = TRUE;
}
- if (StrStr(pCmdLine, L"isoefi=on"))
- {
- gLoadIsoEfi = TRUE;
- }
-
pPos = StrStr(pCmdLine, L"FirstTry=@");
if (pPos)
{
g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset);
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++)
{
chksum += *((UINT8 *)(&(g_chain->os_param)) + i);
return EFI_SUCCESS;
}
-EFI_STATUS EFIAPI ventoy_wrapper_file_open
-(
- EFI_FILE_HANDLE This,
- EFI_FILE_HANDLE *New,
- CHAR16 *Name,
- UINT64 Mode,
- UINT64 Attributes
-)
+EFI_STATUS EFIAPI ventoy_clean_env(VOID)
{
- 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;
+ FreePool(g_sector_flag);
+ g_sector_flag_num = 0;
- 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;
+ gBS->DisconnectController(gBlockData.Handle, NULL, NULL);
- 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;
- }
- }
- }
+ gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle,
+ &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo,
+ &gEfiDevicePathProtocolGuid, gBlockData.Path,
+ NULL);
- return Status;
-}
+ ventoy_delete_variable();
-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))
+ if (g_chain->os_param.vtoy_img_location_addr)
{
- g_original_fopen = (*Root)->Open;
- g_original_fclose = (*Root)->Close;
- (*Root)->Open = ventoy_wrapper_file_open;
+ FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr);
}
- return Status;
+ return EFI_SUCCESS;
}
-
EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
{
UINTN t = 0;
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;
}
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
(
ventoy_install_blockio(ImageHandle, g_iso_buf_size);
Status = ventoy_boot(ImageHandle);
- if (EFI_NOT_FOUND == Status)
- {
- gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n");
- gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n");
- sleep(300);
- }
-
- ventoy_del_ramdisk_param();
+
+ ventoy_delete_ramdisk_param();
}
else
{
- ventoy_set_variable();
+ ventoy_save_variable();
ventoy_find_iso_disk(ImageHandle);
- if (gLoadIsoEfi)
- {
- ventoy_find_iso_disk_fs(ImageHandle);
- ventoy_load_isoefi_driver(ImageHandle);
- }
-
ventoy_debug_pause();
ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes);
ventoy_debug_pause();
Status = ventoy_boot(ImageHandle);
- 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();
}
-
+
+ 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();
gST->ConOut->ClearScreen(gST->ConOut);
return EFI_SUCCESS;
}
-
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
- EFI_HANDLE IsoDriverImage;
}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 trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
UINT64 DiskSize;
}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()
bs->func = wrapper.New##func;\
}
-extern ventoy_efi_file_replace g_efi_file_replace;
extern BOOLEAN gDebugPrint;
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
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
Ventoy.h
Ventoy.c
VentoyDebug.c
+ VentoyProtocol.c
[Packages]
MdePkg/MdePkg.dec
--- /dev/null
+/******************************************************************************
+ * 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;
+}
+
--- /dev/null
+/* 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;
+\f
+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);
+}
enum grub_fshelp_filetype *foundtype;
};
+int g_ventoy_case_insensitive = 0;
+
/* Helper for grub_fshelp_find_file. */
static int
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
{
struct grub_fshelp_find_file_iter_ctx *ctx = data;
+ if (g_ventoy_case_insensitive)
+ {
+ filetype |= GRUB_FSHELP_CASE_INSENSITIVE;
+ }
+
if (filetype == GRUB_FSHELP_UNKNOWN ||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
? grub_strcasecmp (ctx->name, filename)
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_offset = 0;
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
{
- copy_voldesc = 1;
- data->joliet = 1;
+ if (0 == g_ventoy_no_joliet) {
+ copy_voldesc = 1;
+ data->joliet = 1;
+ }
}
if (copy_voldesc)
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)
{
(void)file;
#include <grub/i18n.h>
#include <grub/ventoy.h>
-#define GRUB_CACHE_TIMEOUT 2
+#define GRUB_CACHE_TIMEOUT 10
/* The last time the disk was used. */
static grub_uint64_t grub_last_time = 0;
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_open (const char *name, enum grub_file_type type)
{
#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. */
void __attribute__ ((noreturn))
grub_main (void)
grub_env_export ("root");
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_module_space ();
int g_ventoy_last_entry = 0;
int g_ventoy_suppress_esc = 0;
int g_ventoy_menu_esc = 0;
+int g_ventoy_fn_mutex = 0;
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
goto refresh;
case GRUB_TERM_KEY_F2:
- cmdstr = grub_env_get("VTOY_F2_CMD");
- if (cmdstr)
- {
- menu_fini ();
- grub_script_execute_sourcecode(cmdstr);
- goto refresh;
+ if (0 == g_ventoy_fn_mutex) {
+ cmdstr = grub_env_get("VTOY_F2_CMD");
+ if (cmdstr)
+ {
+ menu_fini ();
+ g_ventoy_fn_mutex = 1;
+ grub_script_execute_sourcecode(cmdstr);
+ g_ventoy_fn_mutex = 0;
+ goto refresh;
+ }
}
break;
case GRUB_TERM_KEY_F3:
- cmdstr = grub_env_get("VTOY_F3_CMD");
- if (cmdstr)
- {
- menu_fini ();
- grub_script_execute_sourcecode(cmdstr);
- goto refresh;
+ if (0 == g_ventoy_fn_mutex) {
+ cmdstr = grub_env_get("VTOY_F3_CMD");
+ if (cmdstr)
+ {
+ menu_fini ();
+ grub_script_execute_sourcecode(cmdstr);
+ goto refresh;
+ }
}
break;
case GRUB_TERM_KEY_F4:
- cmdstr = grub_env_get("VTOY_F4_CMD");
- if (cmdstr)
- {
- menu_fini ();
- grub_script_execute_sourcecode(cmdstr);
- goto refresh;
+ if (0 == g_ventoy_fn_mutex) {
+ cmdstr = grub_env_get("VTOY_F4_CMD");
+ if (cmdstr)
+ {
+ menu_fini ();
+ g_ventoy_fn_mutex = 1;
+ grub_script_execute_sourcecode(cmdstr);
+ g_ventoy_fn_mutex = 0;
+ goto refresh;
+ }
}
break;
case GRUB_TERM_KEY_F5:
- cmdstr = grub_env_get("VTOY_F5_CMD");
- if (cmdstr)
- {
- menu_fini ();
- grub_script_execute_sourcecode(cmdstr);
- goto refresh;
+ if (0 == g_ventoy_fn_mutex) {
+ cmdstr = grub_env_get("VTOY_F5_CMD");
+ if (cmdstr)
+ {
+ menu_fini ();
+ g_ventoy_fn_mutex = 1;
+ grub_script_execute_sourcecode(cmdstr);
+ g_ventoy_fn_mutex = 0;
+ goto refresh;
+ }
}
break;
case GRUB_TERM_KEY_F6:
grub_uint8_t g_ventoy_break_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_uint32_t g_ventoy_cpio_size = 0;
cpio_newc_header *g_ventoy_initrd_head = NULL;
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)
{
int i;
*((img_info **)(node->tail)) = img;
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);
}
}
" %s_%s \n"
"}\n",
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->unsupport ? "unsupport_menuentry" : "common_menuentry");
}
if (strdata && strdata[0] == '/')
{
len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata);
- if (g_img_iterator_head.dir[len] != '/')
+ if (g_img_iterator_head.dir[len - 1] != '/')
{
g_img_iterator_head.dir[len++] = '/';
}
"menuentry \"%s%s\" --id=\"VID_%d\" {\n"
" %s_%s \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->unsupport ? "unsupport_menuentry" : "common_menuentry");
}
void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
{
char *pos;
+ const char *fs = NULL;
grub_uint32_t i;
grub_uint8_t chksum = 0;
grub_disk_t disk;
param->vtoy_reserved[0] = g_ventoy_break_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 */
for (i = 0; i < sizeof(ventoy_os_param); i++)
(void)argc;
(void)args;
+ debug("select auto installation %d\n", argc);
+
if (argc < 1)
{
return 0;
node = ventoy_plugin_find_install_template(args[0]);
if (!node)
{
+ debug("Install template not found for %s\n", args[0]);
return 0;
}
(void)argc;
(void)args;
+ debug("select persistece %d\n", argc);
+
if (argc < 1)
{
return 0;
node = ventoy_plugin_find_persistent(args[0]);
if (!node)
{
+ debug("Persistence image not found for %s\n", args[0]);
return 0;
}
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)
{
(void)ctxt;
(void)argc;
(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();
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)
{
int id = 0;
grub_env_set("vtdebug_flag", "");
grub_env_export("vtdebug_flag");
+
+
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
{ "vt_dump_menu", ventoy_cmd_dump_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_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_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
+ { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
{ "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL },
{ "vt_load_iso_to_mem", ventoy_cmd_load_iso_to_mem, 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_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_locate_wim", ventoy_cmd_wimdows_locate_wim, 0, NULL, "", "", NULL },
{ "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL },
+ { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL },
+ { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL },
+ { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL },
+ { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL },
{ "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL },
{ "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL },
{ "vt_relocator_chaindata", ventoy_cmd_relocator_chaindata, 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_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL },
+
};
{
char path[512];
char name[256];
+
+ const char *alias;
+
int id;
int type;
grub_uint64_t size;
grub_uint32_t new_lookup_align_len;
}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 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
{
const char *key;
ventoy_plugin_entry_pf entryfunc;
+ ventoy_plugin_check_pf checkfunc;
}plugin_entry;
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_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_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
(
struct persistence_config *next;
}persistence_config;
+typedef struct menu_alias
+{
+ int pathlen;
+ char isopath[256];
+ char alias[256];
+
+ struct menu_alias *next;
+}menu_alias;
+
extern int g_ventoy_menu_esc;
extern int g_ventoy_suppress_esc;
extern int g_ventoy_last_entry;
extern int g_ventoy_memdisk_mode;
extern int g_ventoy_iso_raw;
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);
void ventoy_swap_img(img_info *img1, img_info *img2);
void ventoy_plugin_dump_auto_install(void);
int ventoy_fill_windows_rtdata(void *buf, char *isopath);
int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list);
+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_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start);
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__ */
{
va_list args;
+ if (g_ventoy_debug == 0)
+ {
+ return;
+ }
+
va_start (args, fmt);
grub_vprintf (fmt, args);
va_end (args);
}
+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)
{
int sizefilt = 0;
grub_memset(chain, 0, sizeof(ventoy_chain_head));
/* part 1: os parameter */
+ g_ventoy_chain_type = 0;
ventoy_fill_os_param(file, &(chain->os_param));
/* part 2: chain head */
static char g_iso_disk_name[128];
static install_template *g_install_template_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)
{
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)
{
const char *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");
if (value)
{
return 0;
}
+static int ventoy_plugin_check_path(const char *path, const char *file)
+{
+ if (file[0] != '/')
+ {
+ grub_printf("%s is NOT begin with '/' \n", file);
+ return 1;
+ }
+
+ if (grub_strchr(file, '\\'))
+ {
+ grub_printf("%s contains invalid '\\' \n", file);
+ return 1;
+ }
+
+ if (grub_strstr(file, "//"))
+ {
+ grub_printf("%s contains invalid double slash\n", file);
+ return 1;
+ }
+
+ if (grub_strstr(file, "../"))
+ {
+ grub_printf("%s contains invalid '../' \n", file);
+ return 1;
+ }
+
+ if (!ventoy_is_file_exist("%s%s", path, file))
+ {
+ grub_printf("%s%s does NOT exist\n", path, file);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ventoy_plugin_check_fullpath
+(
+ VTOY_JSON *json,
+ const char *isodisk,
+ const char *key
+)
+{
+ int rc = 0;
+ int ret = 0;
+ VTOY_JSON *node = json;
+ VTOY_JSON *child = NULL;
+
+ while (node)
+ {
+ if (0 == grub_strcmp(key, node->pcName))
+ {
+ break;
+ }
+ node = node->pstNext;
+ }
+
+ if (!node)
+ {
+ return 1;
+ }
+
+ if (JSON_TYPE_STRING == node->enDataType)
+ {
+ ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
+ grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
+ }
+ else if (JSON_TYPE_ARRAY == node->enDataType)
+ {
+ for (child = node->pstChild; child; child = child->pstNext)
+ {
+ if (JSON_TYPE_STRING != child->enDataType)
+ {
+ grub_printf("Non string json type\n");
+ }
+ else
+ {
+ rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
+ grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
+ ret += rc;
+ }
+ }
+ }
+
+ return ret;
+}
+
static int ventoy_plugin_parse_fullpath
(
VTOY_JSON *json,
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)
{
int pathnum = 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)
{
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[] =
{
- { "control", ventoy_plugin_control_entry },
- { "theme", ventoy_plugin_theme_entry },
- { "auto_install", ventoy_plugin_auto_install_entry },
- { "persistence", ventoy_plugin_persistence_entry },
+ { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
+ { "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
+ { "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
+ { "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)
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;
+}
+
GRUB_MOD_LICENSE ("GPLv3+");
-wim_hash g_old_hash;
-wim_tail g_wim_data;
+static int g_iso_fs_type = 0;
+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 );
+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)
{
char c1 = vtoy_to_upper(*search);
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)argc;
(void)args;
-
- 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));
+ 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;
+
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_uint64_t file_offset;
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_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2;
}
else
{
- g_wim_data.iso_type = 1;
+ g_iso_fs_type = wim_data->iso_type = 1;
override_len = sizeof(ventoy_udf_override);
override_offset = grub_udf_get_last_file_attr_offset(file, &start_block, &fe_entry_size_offset);
(ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block);
}
- g_wim_data.file_offset = file_offset;
- g_wim_data.udf_start_block = start_block;
- g_wim_data.fe_entry_size_offset = fe_entry_size_offset;
- g_wim_data.override_offset = override_offset;
- g_wim_data.override_len = override_len;
+ wim_data->file_offset = file_offset;
+ wim_data->udf_start_block = start_block;
+ wim_data->fe_entry_size_offset = fe_entry_size_offset;
+ wim_data->override_offset = override_offset;
+ wim_data->override_len = override_len;
return 0;
}
{
wim_directory_entry *wim_dirent = 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);
if (wim_dirent)
return wim_dirent;
}
+ #if 0
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
if (wim_dirent)
{
return wim_dirent;
}
+ #endif
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))
{
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);
- 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)
{
- 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);
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;
char file[256];
ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL);
jump_align = ventoy_align(jump_len, 16);
- g_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;
- g_wim_data.bin_align_len = ventoy_align(g_wim_data.bin_raw_len, 2048);
+ wim_data->jump_exe_len = jump_len;
+ wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len;
+ wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048);
- g_wim_data.jump_bin_data = grub_malloc(g_wim_data.bin_align_len);
- if (g_wim_data.jump_bin_data)
+ wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len);
+ if (wim_data->jump_bin_data)
{
- grub_memcpy(g_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_data, jump_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",
- 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;
}
wim_lookup_entry *meta_look = NULL;
wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL;
- wim_header *head = &(g_wim_data.wim_header);
- wim_lookup_entry *lookup = (wim_lookup_entry *)g_wim_data.new_lookup_data;
+ wim_header *head = NULL;
+ 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);
- if (g_wim_data.jump_bin_data)
+ for (node = g_wim_patch_head; node; node = node->next)
{
- grub_memcpy(g_wim_data.jump_bin_data + jump_align, param, sizeof(ventoy_os_param));
- ventoy_fill_windows_rtdata(g_wim_data.jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath);
- }
+ if (0 == node->valid)
+ {
+ 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;
- rootdir = (wim_directory_entry *)(g_wim_data.new_meta_data + ((security->len + 7) & 0xFFFFFFF8U));
+ jump_align = ventoy_align(wim_data->jump_exe_len, 16);
+ 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 */
- ventoy_update_all_hash(g_wim_data.new_meta_data, rootdir);
+ grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len);
- /* update winpeshl.exe lookup entry data (hash/offset/length) */
- if (g_replace_look)
- {
- 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;
+ security = (wim_security_header *)wim_data->new_meta_data;
+ rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U));
- 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 */
- 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, g_wim_data.new_meta_data, g_wim_data.new_meta_len);
+ /* update winpeshl.exe lookup entry data (hash/offset/length) */
+ if (node->replace_look)
+ {
+ debug("update replace lookup entry_id:%ld\n", ((long)node->replace_look - (long)lookup) / sizeof(wim_lookup_entry));
+ node->replace_look->resource.raw_size = wim_data->bin_raw_len;
+ node->replace_look->resource.size_in_wim = wim_data->bin_raw_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;
}
-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;
grub_file_t file;
wim_security_header *security = NULL;
wim_directory_entry *rootdir = 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;
- (void)argc;
+ debug("windows locate wim start %s\n", patch->path);
- 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)
{
- 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_read(file, head, sizeof(wim_header));
}
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);
lookup = grub_malloc(head->lookup.raw_size);
grub_file_read(file, lookup, head->lookup.raw_size);
/* find and extact winpeshl.exe */
- g_replace_look = ventoy_find_look_entry(head, lookup, &g_old_hash);
- if (g_replace_look)
+ patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash);
+ 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",
- ((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);
}
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;
- g_wim_data.wim_align_size = ventoy_align(g_wim_data.wim_raw_size, 2048);
+ wim_data->wim_raw_size = (grub_uint32_t)file->size;
+ wim_data->wim_align_size = ventoy_align(wim_data->wim_raw_size, 2048);
- check_free(g_wim_data.new_meta_data, grub_free);
- g_wim_data.new_meta_data = decompress_data;
- g_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);
+ grub_check_free(wim_data->new_meta_data);
+ wim_data->new_meta_data = decompress_data;
+ wim_data->new_meta_len = head->metadata.raw_size;
+ wim_data->new_meta_align_len = ventoy_align(wim_data->new_meta_len, 2048);
- check_free(g_wim_data.new_lookup_data, grub_free);
- g_wim_data.new_lookup_data = (grub_uint8_t *)lookup;
- g_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);
+ grub_check_free(wim_data->new_lookup_data);
+ wim_data->new_lookup_data = (grub_uint8_t *)lookup;
+ wim_data->new_lookup_len = (grub_uint32_t)head->lookup.raw_size;
+ wim_data->new_lookup_align_len = ventoy_align(wim_data->new_lookup_len, 2048);
head->metadata.flags = RESHDR_FLAG_METADATA;
- head->metadata.offset = g_wim_data.wim_align_size + g_wim_data.bin_align_len;
- head->metadata.size_in_wim = g_wim_data.new_meta_len;
- head->metadata.raw_size = g_wim_data.new_meta_len;
+ head->metadata.offset = wim_data->wim_align_size + wim_data->bin_align_len;
+ head->metadata.size_in_wim = wim_data->new_meta_len;
+ head->metadata.raw_size = wim_data->new_meta_len;
head->lookup.flags = 0;
- head->lookup.offset = head->metadata.offset + g_wim_data.new_meta_align_len;
- head->lookup.size_in_wim = g_wim_data.new_lookup_len;
- head->lookup.raw_size = g_wim_data.new_lookup_len;
+ head->lookup.offset = head->metadata.offset + wim_data->new_meta_align_len;
+ head->lookup.size_in_wim = wim_data->new_lookup_len;
+ head->lookup.raw_size = wim_data->new_lookup_len;
grub_file_close(file);
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)
{
- /* 1: block count in Partition Descriptor */
- /* 2: file_size in file_entry or extend_file_entry */
- /* 3: data_size and position in extend data short ad */
- /* 4: new wim file header */
- return 4;
+ if (g_iso_fs_type == 0)
+ {
+ /* ISO9660: */
+ /* per wim */
+ /* 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_uint32_t new_wim_size;
ventoy_override_chunk *cur;
+ wim_patch *node = NULL;
+ wim_tail *wim_data = NULL;
+ ventoy_iso9660_override *dirent = NULL;
sector = (isosize + 2047) / 2048;
cur = (ventoy_override_chunk *)override;
- new_wim_size = 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;
+ debug("ventoy_windows_fill_override_data_iso9660 %lu\n", (ulong)isosize);
- 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->size = new_wim_size;
dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
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;
- udf->length = new_wim_size;
- udf->position = (grub_uint32_t)sector - g_wim_data.udf_start_block;
+ wim_data = &node->wim_data;
+ if (node->valid)
+ {
+ 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
cur->img_offset = grub_udf_get_last_pd_size_offset();
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);
- //override 2: filesize in file_entry
- cur++;
- cur->img_offset = g_wim_data.fe_entry_size_offset;
- cur->override_size = 8;
- data64 = new_wim_size;
- grub_memcpy(cur->override_data, &(data64), 8);
-
- /* override 3: position and length in extend data */
- cur++;
- cur->img_offset = g_wim_data.override_offset;
- cur->override_size = g_wim_data.override_len;
- grub_memcpy(cur->override_data, g_wim_data.override_data, cur->override_size);
-
- /* override 4: new wim file header */
- cur++;
- cur->img_offset = g_wim_data.file_offset;
- cur->override_size = sizeof(wim_header);
- grub_memcpy(cur->override_data, &(g_wim_data.wim_header), cur->override_size);
+ for (node = g_wim_patch_head; node; node = node->next)
+ {
+ 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;
+
+ //override 2: filesize in file_entry
+ cur++;
+ cur->img_offset = wim_data->fe_entry_size_offset;
+ cur->override_size = 8;
+ data64 = new_wim_size;
+ grub_memcpy(cur->override_data, &(data64), 8);
+
+ udf = (ventoy_udf_override *)wim_data->override_data;
+ udf->length = new_wim_size;
+ udf->position = (grub_uint32_t)sector - udf_start_block;
+
+ 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;
}
+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)
{
grub_uint64_t sector;
grub_uint32_t mem_secs;
char *override = NULL;
ventoy_virt_chunk *cur = NULL;
+ wim_tail *wim_data = NULL;
+ wim_patch *node = NULL;
sector = (isosize + 2047) / 2048;
- offset = sizeof(ventoy_virt_chunk);
-
- 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;
+ offset = sizeof(ventoy_virt_chunk) * g_wim_valid_patch_count;
override = (char *)chain + chain->virt_chunk_offset;
cur = (ventoy_virt_chunk *)override;
- cur->remap_sector_start = sector;
- cur->remap_sector_end = cur->remap_sector_start + wim_secs;
- cur->org_sector_start = (grub_uint32_t)(g_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;
+ for (node = g_wim_patch_head; node; node = node->next)
+ {
+ if (0 == node->valid)
+ {
+ continue;
+ }
- grub_memcpy(override + offset, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len);
- offset += g_wim_data.bin_align_len;
+ wim_data = &node->wim_data;
- grub_memcpy(override + offset, g_wim_data.new_meta_data, g_wim_data.new_meta_len);
- offset += g_wim_data.new_meta_align_len;
-
- grub_memcpy(override + offset, g_wim_data.new_lookup_data, g_wim_data.new_lookup_len);
- offset += g_wim_data.new_lookup_align_len;
+ wim_secs = wim_data->wim_align_size / 2048;
+ mem_secs = (wim_data->bin_align_len + wim_data->new_meta_align_len + wim_data->new_lookup_align_len) / 2048;
+
+ cur->remap_sector_start = sector;
+ 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 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;
debug("Warning: %s was not recognized by Ventoy\n", args[0]);
else
{
override_size = ventoy_get_override_chunk_num() * sizeof(ventoy_override_chunk);
- virt_chunk_size = sizeof(ventoy_virt_chunk) + g_wim_data.bin_align_len +
- g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len;;
+ virt_chunk_size = ventoy_windows_get_virt_data_size();
size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size;
}
grub_memset(chain, 0, sizeof(ventoy_chain_head));
/* part 1: os parameter */
+ g_ventoy_chain_type = 1;
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]);
}
return 0;
}
- if (g_wim_data.new_meta_data == NULL)
+ if (0 == g_wim_valid_patch_count)
{
return 0;
}
/* part 4: override chunk */
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
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 */
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);
if (ventoy_is_efi_os() == 0)
grub_memset(chain, 0, sizeof(ventoy_chain_head));
/* part 1: os parameter */
+ g_ventoy_chain_type = 0;
ventoy_fill_os_param(file, &(chain->os_param));
/* part 2: chain head */
--- /dev/null
+/*
+ * 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 */
*
* vtoy_reserved[0]: vtoy_break_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
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);
+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_file_dirent_pos(grub_file_t file);
grub_uint64_t grub_udf_get_file_offset(grub_file_t file);
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
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"
-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
. $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
. $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_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace"
else
- if $GREP -q kaspersky /proc/version; then
- $SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
- else
- $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
- fi
+ $SED "/mdev *-s/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init
fi
--- /dev/null
+#!/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
--- /dev/null
+#!/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
#!/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
-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"
--- /dev/null
+#!/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
. /ventoy/hook/ventoy-hook-lib.sh
-if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then
- exit 0
-fi
-
-ventoy_udev_disk_common_hook $*
+vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt)
-#
-# 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
+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
#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"
$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_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"
VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs"
break
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
echo "VTKS=$VTKS" >> $VTLOG
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
-$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/01-ventoy-timeout.sh
+#Fedora
+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
if [ -e /usr/sbin/anaconda-diskroot ]; then
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
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 ..."
$BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace
ventoy_swap_device /dev/dm-0 /dev/$vtDM
fi
- vtlog "set anaconda-diskroot ..."
- /sbin/anaconda-diskroot /dev/dm-0
- #/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/dm-0
+ if [ -e /sbin/anaconda-diskroot ]; then
+ vtlog "set anaconda-diskroot ..."
+ /sbin/anaconda-diskroot /dev/dm-0
+ fi
set_ventoy_hook_finish
fi
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})
-vtlog "diskroot $vtDM ..."
-/sbin/anaconda-diskroot /dev/dm-0
-#/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/$vtDM
+if [ -e /sbin/anaconda-diskroot ]; then
+ vtlog "set anaconda-diskroot ..."
+ /sbin/anaconda-diskroot /dev/dm-0
+fi
PATH=$VTPATH_OLD
# #
####################################################################
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() {
#As I known, PCLinuxOS use ramdisk
elif $EGREP -q 'archlinux|ARCH' /proc/version; then
echo 'arch'; return
+ # kiosk
+ elif $EGREP -q 'kiosk' /proc/version; then
+ echo 'kiosk'; return
+
# gentoo
elif $EGREP -q '[Gg]entoo' /proc/version; then
echo 'gentoo'; return
fi
-
####################################################################
# #
# Step 4 : Hand over to real init #
--- /dev/null
+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 ...'
+}
#
#************************************************************************************
+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 {
- 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 {
- 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
+ set vtoy_os=Linux
+
+ 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
break
fi
done
-
+
if [ -n "${vtdebug_flag}" ]; then
echo ISO is $vtoy_os
fi
}
-function vt_check_pe {
- unset VT_PE_SUPPORT
-
+function vt_check_compatible_pe {
+ #Check for PE without external tools
if [ -f $1/HBCD_PE.ini ]; then
- 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
+ set ventoy_compatible=YES
fi
}
function locate_initrd {
vt_linux_locate_initrd
- if [ -n "${vtdebug_flag}" ]; then
+ if [ -n "${vtdebug_flag}" ]; then
vt_linux_dump_initrd
- sleep 5
+ ventoy_debug_pause
fi
}
-function find_wim_file {
- unset ventoy_wim_file
+function locate_wim {
+ vt_windows_locate_wim_patch (loop)
- for file in "sources/boot.wim" "sources/BOOT.WIM" "Sources/Win10PEx64.WIM" "boot/BOOT.WIM" \
- "winpe_x64.wim" "boot/10pex64.wim" "BOOT/USM1PE6L.WIM" "BOOT/USM1PE6F.WIM"; do
- if [ -e $1/$file ]; then
- set ventoy_wim_file=$1/$file
- break
- fi
- done
+ if [ -n "${vtdebug_flag}" ]; then
+ echo '###############################################'
+ vt_dump_wim_patch
+ echo '###############################################'
+ ventoy_debug_pause
+ fi
}
+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 {
if [ -e (loop)/boot/all.rdz ]; then
vt_linux_specify_initrd_file /boot/all.rdz
function uefi_windows_menu_func {
vt_windows_reset
-
- if [ "$ventoy_compatible" = "NO" ]; then
- find_wim_file (loop)
- if [ -n "$ventoy_wim_file" ]; then
- vt_windows_locate_wim $ventoy_wim_file
+
+ if [ "$ventoy_compatible" = "NO" ]; then
+
+ if [ "$ventoy_fs_probe" = "iso9660" ]; then
+ loopback -d loop
+ vt_iso9660_nojoliet 1
+ loopback loop $1$2
fi
- fi
-
- vt_windows_chain_data ${1}${chosen_path}
+
+ for file in "efi/microsoft/boot/bcd"; do
+ vt_windows_collect_wim_patch bcd (loop)/$file
+ done
- if [ -n "${vtdebug_flag}" ]; then
- sleep 5
+ 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
+ vt_windows_chain_data ${1}${chosen_path}
+ ventoy_debug_pause
+
if [ -n "$vtoy_chain_mem_addr" ]; then
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}
boot
else
echo "chain empty failed"
- sleep 5
+ ventoy_pause
fi
}
function uefi_linux_menu_func {
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_linux_clear_initrd
fi
done
fi
-
+
# special process for special distros
if [ -d (loop)/loader/entries ]; then
- set LoadIsoEfiDriver=on
vt_linux_parse_initrd_grub dir (loop)/loader/entries/
elif [ -d (loop)/boot/grub ]; then
vt_linux_parse_initrd_grub dir (loop)/boot/grub/
fi
- if [ -e (loop)/syslinux/alt0/full.cz ]; then
- set LoadIsoEfiDriver=on
- set FirstTryBootFile='@EFI@BOOT@grubx64.efi'
- fi
-
distro_specify_initrd_file
vt_linux_initrd_count vtcount
fi
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
vt_linux_chain_data ${1}${chosen_path}
boot
else
echo "chain empty failed"
- sleep 5
+ ventoy_pause
fi
}
set ventoy_fs_probe=udf
else
set ventoy_fs_probe=iso9660
+ vt_iso9660_nojoliet 0
fi
loopback loop ${1}${chosen_path}
vt_img_sector ${1}${chosen_path}
if [ "$vtoy_os" = "Windows" ]; then
- vt_check_pe (loop)
- if [ "$VT_PE_SUPPORT" != "YES" ]; then
- if [ "$ventoy_fs_probe" = "iso9660" ]; then
- set ventoy_compatible=YES
- fi
- fi
-
+ vt_check_compatible_pe (loop)
uefi_windows_menu_func $1 ${chosen_path}
else
uefi_linux_menu_func $1 ${chosen_path}
function legacy_windows_menu_func {
vt_windows_reset
- if [ "$ventoy_compatible" = "NO" ]; then
- find_wim_file (loop)
- if [ -n "$ventoy_wim_file" ]; then
- vt_windows_locate_wim $ventoy_wim_file
- elif [ -n "${vtdebug_flag}" ]; then
- echo No wim file found
+ if [ "$ventoy_compatible" = "NO" ]; then
+
+ if [ "$ventoy_fs_probe" = "iso9660" ]; then
+ loopback -d loop
+ vt_iso9660_nojoliet 1
+ loopback loop $1$2
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
-
- vt_windows_chain_data ${1}${chosen_path}
-
- if [ -n "${vtdebug_flag}" ]; then
- sleep 5
- fi
+
+ vt_windows_chain_data ${1}${chosen_path}
+ ventoy_debug_pause
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}
boot
else
echo "chain empty failed"
- sleep 5
+ ventoy_pause
fi
}
function legacy_linux_menu_func {
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_linux_clear_initrd
locate_initrd
fi
- vt_linux_chain_data ${1}${chosen_path}
-
- if [ -n "${vtdebug_flag}" ]; then
- sleep 5
- fi
+ vt_linux_chain_data ${1}${chosen_path}
+ ventoy_debug_pause
if [ -n "$vtoy_chain_mem_addr" ]; then
linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size}
boot
else
echo "chain empty failed"
- sleep 5
+ ventoy_pause
fi
}
set ventoy_fs_probe=udf
else
set ventoy_fs_probe=iso9660
- fi
-
- loopback loop ${1}${chosen_path}
+ vt_iso9660_nojoliet 0
+ fi
+ loopback loop ${1}${chosen_path}
get_os_type (loop)
-
+
if [ -n "$vtcompat" ]; then
set ventoy_compatible=YES
unset vtcompat
vt_img_sector ${1}${chosen_path}
if [ "$vtoy_os" = "Windows" ]; then
- vt_check_pe (loop)
- if [ "$VT_PE_SUPPORT" != "YES" ]; then
- if [ "$ventoy_fs_probe" = "iso9660" ]; then
- set ventoy_compatible=YES
- fi
- fi
-
+ vt_check_compatible_pe (loop)
legacy_windows_menu_func $1 ${chosen_path}
else
legacy_linux_menu_func $1 ${chosen_path}
function wim_common_menuentry {
vt_chosen_img_path chosen_path
- vt_wim_chain_data ${iso_path}${chosen_path}
- if [ -n "${vtdebug_flag}" ]; then
- sleep 5
- fi
+ vt_wim_chain_data ${iso_path}${chosen_path}
+
+ ventoy_debug_pause
if [ -n "$vtoy_chain_mem_addr" ]; then
if [ "$grub_platform" = "pc" ]; then
boot
else
echo "chain empty failed"
- sleep 5
+ ventoy_pause
fi
}
#############################################################
#############################################################
-set VENTOY_VERSION="1.0.12"
+set VENTOY_VERSION="1.0.13"
# Default menu display mode, you can change it as you want.
# 0: List mode
unset timeout
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_F2_CMD="ventoy_power"
+set VTOY_F4_CMD="ventoy_localboot"
+set VTOY_F5_CMD="ventoy_diagnosis"
if [ "$grub_platform" = "pc" ]; then
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net"
vt_device $root vtoy_dev
if [ "$vtoy_dev" = "tftp" ]; then
- set vtoy_path=($root)
+ set vtoy_path=($root)
for vtid in 0 1 2 3; do
if [ -d (hd$vtid,2)/ventoy ]; then
set iso_path=(hd$vtid,1)
break
fi
done
+ loadfont ascii
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 vtoy_efi_part=($vtoy_dev,2)
+ loadfont unicode
fi
-loadfont ascii
#Load Plugin
if [ -f $iso_path/ventoy/ventoy.json ]; then
if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then
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
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
set theme=$prefix/themes/ventoy/theme.txt
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)
set ventoy_img_count=0
--- /dev/null
+
+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 ...'
+}
menuentry Halt {
echo -e '\n\nSystem is halting ... \n'
sleep 1
- reboot
+ halt
}
menuentry 'Return to menu [Esc]' VTOY_RET {
desktop-image: "background.png"
title-text: " "
-title-font: "ascii"
title-color: "#ffffff"
-message-font: "ascii"
message-color: "#f2f2f2"
terminal-box: "terminal_box_*.png"
menu_pixmap_style = "menu_*.png"
- item_font = "ascii"
item_color = "#ffffff"
item_height = 30
item_spacing = 1
item_padding = 1
- selected_item_font = "ascii"
selected_item_color= "#f2f2f2"
selected_item_pixmap_style = "select_*.png"
+ hbox{
- left = 90%
- top = 30
+ left = 30%
+ top = 95%-50
width = 10%
height = 25
+ label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"}
echo "create efi fat fs $PART2 ..."
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'
break
else
uint32_t g_img_chunk_num;
ventoy_img_chunk *g_cur_chunk;
uint32_t g_disk_sector_size;
+uint8_t *g_os_param_reserved;
+
ventoy_override_chunk *g_override_chunk;
uint32_t g_override_chunk_num;
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 );
#define ventoy_address __use_data16 ( ventoy_address )
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:
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)
{
uint32_t i, j;
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;
if (readend <= g_chain->real_img_size_in_bytes)
{
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[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_len=<%u>\n", chain->os_param.vtoy_img_location_len);
ventoy_debug_pause();
g_disk_sector_size = g_chain->disk_sector_size;
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_num = g_chain->override_chunk_num;
grub_uint8_t reserved[31];
}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()
// compile assert to check that size of ventoy_os_param must be 512
static CHAR GetMountLogicalDrive(void)
{
- CHAR Letter = 'Z';
+ CHAR Letter = 'Y';
DWORD Drives;
- DWORD Mask = 0x2000000;
+ DWORD Mask = 0x1000000;
Drives = GetLogicalDrives();
Log("Drives=0x%x", Drives);
-
+
while (Mask)
{
if ((Drives & Mask) == 0)
{
Letter = 'X';
}
-
+
sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter);
Log("Copy file <%s> --> <%s>", script, CurDir);
CopyFile(script, CurDir, FALSE);