diff --git a/DOC/BuildVentoyFromSource.txt b/DOC/BuildVentoyFromSource.txt index 4c20700e..191f9548 100644 --- a/DOC/BuildVentoyFromSource.txt +++ b/DOC/BuildVentoyFromSource.txt @@ -199,5 +199,7 @@ 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 diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c index 3b83dd5a..c05e772f 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -36,34 +36,24 @@ #include #include -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[] = @@ -76,9 +66,6 @@ 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; @@ -204,6 +191,12 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain) debug("os_param->vtoy_img_size=<%llu>", chain->os_param.vtoy_img_size); debug("os_param->vtoy_img_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(); @@ -224,312 +217,102 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain) 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) @@ -545,7 +328,7 @@ 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; @@ -559,7 +342,7 @@ EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID) } -EFI_STATUS EFIAPI ventoy_set_variable(VOID) +EFI_STATUS EFIAPI ventoy_save_variable(VOID) { EFI_STATUS Status = EFI_SUCCESS; EFI_GUID VarGuid = VENTOY_GUID; @@ -585,56 +368,7 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID) 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, @@ -745,156 +479,6 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) } } -STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle) -{ - UINTN i = 0; - UINTN Count = 0; - EFI_HANDLE Parent = NULL; - EFI_HANDLE *Handles = NULL; - EFI_STATUS Status = EFI_SUCCESS; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; - EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; - - Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, - NULL, &Count, &Handles); - if (EFI_ERROR(Status)) - { - return Status; - } - - debug("ventoy_find_iso_disk_fs fs count:%u", Count); - - for (i = 0; i < Count; i++) - { - Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); - if (EFI_ERROR(Status)) - { - continue; - } - - Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, - (VOID **)&pDevPath, - ImageHandle, - Handles[i], - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (EFI_ERROR(Status)) - { - debug("Failed to open device path protocol %r", Status); - continue; - } - - debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); - Parent = ventoy_get_parent_handle(pDevPath); - - if (Parent == gBlockData.RawBlockIoHandle) - { - debug("Find ventoy disk fs"); - gBlockData.DiskFsHandle = Handles[i]; - gBlockData.pDiskFs = pFile; - gBlockData.pDiskFsDevPath = pDevPath; - break; - } - } - - FreePool(Handles); - - return EFI_SUCCESS; -} - -STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle) -{ - EFI_HANDLE Image = NULL; - EFI_STATUS Status = EFI_SUCCESS; - CHAR16 LogVar[4] = L"5"; - - Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, - gIso9660EfiDriverPath, - sizeof(gIso9660EfiDriverPath), - &Image); - debug("load iso efi driver status:%r", Status); - - if (gDebugPrint) - { - gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(LogVar), LogVar); - } - - gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(LogVar), LogVar); - - gBlockData.IsoDriverImage = Image; - Status = gBS->StartImage(Image, NULL, NULL); - debug("Start iso efi driver status:%r", Status); - - return EFI_SUCCESS; -} - -static int ventoy_update_image_location(ventoy_os_param *param) -{ - EFI_STATUS Status = EFI_SUCCESS; - UINT8 chksum = 0; - unsigned int i; - unsigned int length; - UINTN address = 0; - void *buffer = NULL; - ventoy_image_location *location = NULL; - ventoy_image_disk_region *region = NULL; - ventoy_img_chunk *chunk = g_chunk; - - length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region); - - Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer); - if (EFI_ERROR(Status) || NULL == buffer) - { - debug("Failed to allocate runtime pool %r\n", Status); - return 1; - } - - address = (UINTN)buffer; - - if (address % 4096) - { - address += 4096 - (address % 4096); - } - - param->chksum = 0; - param->vtoy_img_location_addr = address; - param->vtoy_img_location_len = length; - - /* update check sum */ - for (i = 0; i < sizeof(ventoy_os_param); i++) - { - chksum += *((UINT8 *)param + i); - } - param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum); - - location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr); - if (NULL == location) - { - return 0; - } - - CopyMem(&location->guid, ¶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; @@ -923,11 +507,6 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) gDebugPrint = TRUE; } - if (StrStr(pCmdLine, L"isoefi=on")) - { - gLoadIsoEfi = TRUE; - } - pPos = StrStr(pCmdLine, L"FirstTry=@"); if (pPos) { @@ -998,6 +577,14 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); g_virt_chunk_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); @@ -1020,82 +607,28 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) 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; @@ -1179,7 +712,7 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC) { - g_original_open_volume = pFile->OpenVolume; + ventoy_wrapper_push_openvolume(pFile->OpenVolume); pFile->OpenVolume = ventoy_wrapper_open_volume; } @@ -1210,74 +743,6 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) 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 ( @@ -1309,26 +774,14 @@ 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); @@ -1336,32 +789,20 @@ EFI_STATUS EFIAPI VentoyEfiMain 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; } - diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h index eb22e772..48c68c8b 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h @@ -199,10 +199,8 @@ typedef struct vtoy_block_data 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__) @@ -254,6 +252,14 @@ typedef struct ventoy_ram_disk 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() @@ -282,7 +288,6 @@ typedef struct ventoy_system_wrapper 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); @@ -296,5 +301,30 @@ EFI_STATUS EFIAPI ventoy_block_io_read 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 diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf index 1db9b218..00a5e548 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf @@ -29,6 +29,7 @@ Ventoy.h Ventoy.c VentoyDebug.c + VentoyProtocol.c [Packages] MdePkg/MdePkg.dec diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c new file mode 100644 index 00000000..624055df --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -0,0 +1,631 @@ +/****************************************************************************** + * Ventoy.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c new file mode 100644 index 00000000..6f1900d2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c @@ -0,0 +1,491 @@ +/* test.c -- The test command.. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 + will be added to the first mtime. */ + if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0 + || grub_memcmp (args[*argn + 1], "-ot", 3) == 0) + { + struct grub_dirhook_info file1; + int file1exists; + int bias = 0; + + /* Fetch fileinfo. */ + get_fileinfo (args[*argn], &ctx); + file1 = ctx.file_info; + file1exists = ctx.file_exists; + get_fileinfo (args[*argn + 2], &ctx); + + if (args[*argn + 1][3]) + bias = grub_strtosl (args[*argn + 1] + 3, 0, 0); + + if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0) + update_val ((file1exists && ! ctx.file_exists) + || (file1.mtimeset && ctx.file_info.mtimeset + && file1.mtime + bias > ctx.file_info.mtime), + &ctx); + else + update_val ((! file1exists && ctx.file_exists) + || (file1.mtimeset && ctx.file_info.mtimeset + && file1.mtime + bias < ctx.file_info.mtime), + &ctx); + (*argn) += 3; + continue; + } + } + + /* Two-argument tests. */ + if (*argn + 1 < argc) + { + /* File tests. */ + if (grub_strcmp (args[*argn], "-d") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-D") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-e") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + update_val (ctx.file_exists, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-E") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + update_val (ctx.file_exists, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-f") == 0) + { + get_fileinfo (args[*argn + 1], &ctx); + /* FIXME: check for other types. */ + update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + if (grub_strcmp (args[*argn], "-F") == 0) + { + g_test_case_insensitive = 1; + get_fileinfo (args[*argn + 1], &ctx); + g_test_case_insensitive = 0; + /* FIXME: check for other types. */ + update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + (*argn) += 2; + continue; + } + + if (grub_strcmp (args[*argn], "-s") == 0) + { + grub_file_t file; + file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE + | GRUB_FILE_TYPE_NO_DECOMPRESS); + update_val (file && (grub_file_size (file) != 0), &ctx); + if (file) + grub_file_close (file); + grub_errno = GRUB_ERR_NONE; + (*argn) += 2; + continue; + } + + /* String tests. */ + if (grub_strcmp (args[*argn], "-n") == 0) + { + update_val (args[*argn + 1][0], &ctx); + + (*argn) += 2; + continue; + } + if (grub_strcmp (args[*argn], "-z") == 0) + { + update_val (! args[*argn + 1][0], &ctx); + (*argn) += 2; + continue; + } + } + + /* Special modifiers. */ + + /* End of expression. return to parent. */ + if (grub_strcmp (args[*argn], ")") == 0) + { + (*argn)++; + return ctx.or || ctx.and; + } + /* Recursively invoke if parenthesis. */ + if (grub_strcmp (args[*argn], "(") == 0) + { + (*argn)++; + update_val (test_parse (args, argn, argc), &ctx); + continue; + } + + if (grub_strcmp (args[*argn], "!") == 0) + { + ctx.invert = ! ctx.invert; + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-a") == 0) + { + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-o") == 0) + { + ctx.or = ctx.or || ctx.and; + ctx.and = 1; + (*argn)++; + continue; + } + + /* No test found. Interpret if as just a string. */ + update_val (args[*argn][0], &ctx); + (*argn)++; + } + return ctx.or || ctx.and; +} + +static grub_err_t +grub_cmd_test (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int argn = 0; + + if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) + argc--; + + return test_parse (args, &argn, argc) ? GRUB_ERR_NONE + : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); +} + +static grub_command_t cmd_1, cmd_2; + +GRUB_MOD_INIT(test) +{ + cmd_1 = grub_register_command ("[", grub_cmd_test, + N_("EXPRESSION ]"), N_("Evaluate an expression.")); + cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; + cmd_2 = grub_register_command ("test", grub_cmd_test, + N_("EXPRESSION"), N_("Evaluate an expression.")); + cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; +} + +GRUB_MOD_FINI(test) +{ + grub_unregister_command (cmd_1); + grub_unregister_command (cmd_2); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c index 5901fac4..f5b6772e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c @@ -117,6 +117,8 @@ struct grub_fshelp_find_file_iter_ctx 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, @@ -124,6 +126,11 @@ 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) diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c index f0e7dcfb..5785c6f3 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c @@ -32,6 +32,7 @@ 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; @@ -480,8 +481,10 @@ grub_iso9660_mount (grub_disk_t disk) (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) @@ -1108,6 +1111,11 @@ grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) 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; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c index 9cb38425..04d6ce76 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c @@ -27,7 +27,7 @@ #include #include -#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; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c index b01bfad4..b4d5238c 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c @@ -83,6 +83,29 @@ grub_file_t grub_memfile_open(const char *name) 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) { diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c index 43b2de98..2f22ecb5 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c @@ -260,6 +260,45 @@ reclaim_module_space (void) #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) @@ -293,6 +332,12 @@ 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 (); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c index 6c10f4ab..e416c6f3 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c @@ -41,6 +41,7 @@ int g_ventoy_iso_uefi_drv = 0; int g_ventoy_last_entry = 0; int g_ventoy_suppress_esc = 0; int g_ventoy_menu_esc = 0; +int g_ventoy_fn_mutex = 0; /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -802,39 +803,53 @@ run_menu (grub_menu_t menu, int nested, int *auto_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: diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index 1ad4ebe8..93641ee3 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -68,6 +68,7 @@ img_iterator_node *g_img_iterator_tail = NULL; grub_uint8_t g_ventoy_break_level = 0; grub_uint8_t g_ventoy_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; @@ -433,6 +434,27 @@ static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int arg 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; @@ -853,6 +875,8 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho *((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); } } @@ -1031,7 +1055,8 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node) " %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"); } @@ -1115,7 +1140,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char 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++] = '/'; } @@ -1174,7 +1199,8 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char "menuentry \"%s%s\" --id=\"VID_%d\" {\n" " %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"); } @@ -1394,6 +1420,7 @@ int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) { char *pos; + const char *fs = NULL; grub_uint32_t i; grub_uint8_t chksum = 0; grub_disk_t disk; @@ -1419,6 +1446,14 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) param->vtoy_reserved[0] = g_ventoy_break_level; param->vtoy_reserved[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++) @@ -1567,6 +1602,8 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar (void)argc; (void)args; + debug("select auto installation %d\n", argc); + if (argc < 1) { return 0; @@ -1575,6 +1612,7 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar node = ventoy_plugin_find_install_template(args[0]); if (!node) { + debug("Install template not found for %s\n", args[0]); return 0; } @@ -1622,6 +1660,8 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg (void)argc; (void)args; + debug("select persistece %d\n", argc); + if (argc < 1) { return 0; @@ -1630,6 +1670,7 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg node = ventoy_plugin_find_persistent(args[0]); if (!node) { + debug("Persistence image not found for %s\n", args[0]); return 0; } @@ -1854,12 +1895,51 @@ static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, cha return 0; } +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; @@ -1962,6 +2042,31 @@ static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, 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; @@ -2109,6 +2214,8 @@ static int ventoy_env_init(void) 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); @@ -2146,11 +2253,13 @@ static cmd_para ventoy_cmds[] = { "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 }, @@ -2164,18 +2273,25 @@ static cmd_para ventoy_cmds[] = { "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 }, + }; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index da6e6889..c621b1f8 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -132,6 +132,9 @@ typedef struct img_info { char path[512]; char name[256]; + + const char *alias; + int id; int type; grub_uint64_t size; @@ -363,6 +366,19 @@ typedef struct wim_tail 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 @@ -412,11 +428,13 @@ typedef struct _JSON_PARSE } 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; @@ -440,9 +458,9 @@ int ventoy_is_file_exist(const char *fmt, ...); 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 ( @@ -596,12 +614,23 @@ typedef struct persistence_config 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); @@ -611,9 +640,15 @@ persistence_config * ventoy_plugin_find_persistent(const char *isopath); 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__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c index 8a4e8b10..b9e4a743 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c @@ -42,6 +42,11 @@ static void json_debug(const char *fmt, ...) { va_list args; + if (g_ventoy_debug == 0) + { + return; + } + va_start (args, fmt); grub_vprintf (fmt, args); va_end (args); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c index 1e795c3c..ddd7499a 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -841,6 +841,50 @@ static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt) } +grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int index = 0; + char buf[32]; + initrd_info *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return 1; + } + + if (g_initrd_img_count == 1) + { + ventoy_set_env(args[0], "0"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + + for (node = g_initrd_img_list; node; node = node->next) + { + if (node->size <= 0) + { + continue; + } + + if (grub_strstr(node->name, "ucode") || grub_strstr(node->name, "-firmware")) + { + index++; + continue; + } + + grub_snprintf(buf, sizeof(buf), "%d", index); + ventoy_set_env(args[0], buf); + break; + } + + debug("main initrd index:%d\n", index); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args) { int sizefilt = 0; @@ -1100,6 +1144,7 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ + g_ventoy_chain_type = 0; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c index 4aad58d8..1948d0af 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -41,6 +41,46 @@ GRUB_MOD_LICENSE ("GPLv3+"); 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) { @@ -70,6 +110,64 @@ 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; @@ -104,6 +202,13 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) 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) { @@ -125,6 +230,92 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) 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, @@ -209,6 +400,46 @@ static int ventoy_plugin_parse_fullpath 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; @@ -264,6 +495,45 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk 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) { @@ -322,13 +592,93 @@ 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) @@ -566,3 +916,100 @@ end: 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; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c index 6ca05632..438b6985 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c @@ -40,13 +40,229 @@ 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); @@ -96,16 +312,24 @@ static int ventoy_is_pe64(grub_uint8_t *buffer) grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args) { + 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; } @@ -159,7 +383,7 @@ end: 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; @@ -169,7 +393,7 @@ static int ventoy_get_override_info(grub_file_t file) 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; @@ -181,7 +405,7 @@ static int ventoy_get_override_info(grub_file_t file) } 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); @@ -191,11 +415,11 @@ static int ventoy_get_override_info(grub_file_t file) (ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block); } - 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; } @@ -336,7 +560,7 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire { 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) @@ -344,11 +568,13 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire 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; } @@ -394,7 +620,7 @@ static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_ 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)) { @@ -408,15 +634,15 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir) 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); @@ -425,7 +651,7 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir) 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]; @@ -439,19 +665,19 @@ static int ventoy_cat_exe_file_data(grub_uint32_t exe_len, grub_uint8_t *exe_dat ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL); 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; } @@ -490,49 +716,63 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath) 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; @@ -543,20 +783,22 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c wim_security_header *security = NULL; wim_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)); @@ -596,8 +838,8 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c } debug("find replace file at %p\n", search); - - 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); @@ -605,16 +847,16 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c grub_file_read(file, lookup, head->lookup.raw_size); /* 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 @@ -624,106 +866,236 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c } 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; @@ -732,37 +1104,53 @@ static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chai 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; } @@ -828,7 +1216,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c 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]); @@ -871,8 +1259,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c 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; } @@ -903,9 +1290,10 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* 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]); } @@ -934,7 +1322,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c return 0; } - if (g_wim_data.new_meta_data == NULL) + if (0 == g_wim_valid_patch_count) { return 0; } @@ -942,11 +1330,19 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c /* part 4: override chunk */ 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) @@ -1099,6 +1495,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ + g_ventoy_chain_type = 0; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h new file mode 100644 index 00000000..6c4203cb --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h @@ -0,0 +1,243 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FILE_HEADER +#define GRUB_FILE_HEADER 1 + +#include +#include +#include +#include +#include + +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 */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h index 799bfb4e..6c320725 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h @@ -109,6 +109,8 @@ typedef struct ventoy_os_param * * 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 @@ -227,6 +229,7 @@ typedef struct ventoy_grub_param int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); int grub_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); diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh index 45a28f0d..93033083 100644 --- a/GRUB2/MOD_SRC/grub-2.04/install.sh +++ b/GRUB2/MOD_SRC/grub-2.04/install.sh @@ -12,10 +12,10 @@ make install 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 diff --git a/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh b/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh index a73b7027..d29eddfc 100644 --- a/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/clear/ventoy-hook.sh @@ -19,4 +19,10 @@ . $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 diff --git a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh index ce5dbe5e..e4d90ee7 100644 --- a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh @@ -19,13 +19,11 @@ . $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 diff --git a/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh b/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh new file mode 100644 index 00000000..2c934278 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh @@ -0,0 +1,70 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /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 diff --git a/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh new file mode 100644 index 00000000..31e5b96f --- /dev/null +++ b/IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED '/^ *search [^(]*$/i\ /ventoy/busybox/sh /ventoy/hook/kiosk/ventoy-disk.sh' -i /init diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh index 5edc8f2b..05c6c412 100644 --- a/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-hook.sh @@ -1,7 +1,29 @@ #!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ . $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" diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..bc604ffd --- /dev/null +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh @@ -0,0 +1,69 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /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 diff --git a/IMG/cpio/ventoy/hook/mageia/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh similarity index 62% rename from IMG/cpio/ventoy/hook/mageia/udev_disk_hook.sh rename to IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh index b685c71d..6be81555 100644 --- a/IMG/cpio/ventoy/hook/mageia/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-start.sh @@ -19,22 +19,13 @@ . /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 diff --git a/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh index 388c92cf..d84f0bc8 100644 --- a/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/rhel6/udev_disk_hook.sh @@ -64,7 +64,7 @@ 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" diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh index e66dbc5a..beb41e13 100644 --- a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh @@ -22,6 +22,5 @@ $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" diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index 431d58a4..1bb6a6b1 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -31,7 +31,13 @@ else 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 @@ -44,8 +50,15 @@ fi 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 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh index d79bb2df..a565098b 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh @@ -28,6 +28,16 @@ vtlog "##### INOTIFYD: $2/$3 is created ..." 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 @@ -41,9 +51,10 @@ if is_inotify_ventoy_part $3; then 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 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh index a5db322c..87ece3be 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh @@ -26,8 +26,9 @@ VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') 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 diff --git a/IMG/cpio/ventoy/init b/IMG/cpio/ventoy/init index c2b7b507..61659fc3 100644 --- a/IMG/cpio/ventoy/init +++ b/IMG/cpio/ventoy/init @@ -51,7 +51,17 @@ fi # # #################################################################### 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 diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy.sh index edab7e8c..84f54923 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy.sh @@ -87,6 +87,10 @@ ventoy_get_os_type() { 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 @@ -215,7 +219,6 @@ if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then fi - #################################################################### # # # Step 4 : Hand over to real init # diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index e6ba9bb6..292c37ac 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg new file mode 100644 index 00000000..9e74ac7b --- /dev/null +++ b/INSTALL/grub/debug.cfg @@ -0,0 +1,57 @@ +submenu 'Check plugin json configuration (ventoy.json)' { + menuentry 'Check global control plugin configuration' { + set pager=1 + vt_check_plugin_json $iso_path control $iso_path + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check theme plugin configuration' { + set pager=1 + vt_check_plugin_json $iso_path theme $iso_path + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check auto install plugin configuration' { + set pager=1 + vt_check_plugin_json $iso_path auto_install $iso_path + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check persistence plugin configuration' { + set pager=1 + vt_check_plugin_json $iso_path persistence $iso_path + + echo -e "\n############### dump persistence ###############" + vt_dump_persistence + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check menu alias plugin configuration' { + set pager=1 + vt_check_plugin_json $iso_path menu_alias $iso_path + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Return to previous menu [Esc]' VTOY_RET { + echo 'Return ...' + } +} + +menuentry 'Return to previous menu [Esc]' VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/grub/fonts/ascii.pf2 b/INSTALL/grub/fonts/ascii.pf2 index 1eb3edcf..d81ac8b9 100644 Binary files a/INSTALL/grub/fonts/ascii.pf2 and b/INSTALL/grub/fonts/ascii.pf2 differ diff --git a/INSTALL/grub/fonts/unicode.pf2 b/INSTALL/grub/fonts/unicode.pf2 new file mode 100644 index 00000000..b340859c Binary files /dev/null and b/INSTALL/grub/fonts/unicode.pf2 differ diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index b1ef9b0a..e7627f65 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -16,60 +16,91 @@ # #************************************************************************************ +function ventoy_pause { + if [ -n "${vtdebug_flag}" ]; then + echo "press Enter to continue ......" + read vtTmpPause + fi +} + +function ventoy_debug_pause { + if [ -n "${vtdebug_flag}" ]; then + echo "press Enter to continue ......" + read vtTmpPause + fi +} + + function ventoy_power { - 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 @@ -127,32 +158,50 @@ function distro_specify_initrd_file_phase2 { 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 @@ -166,20 +215,14 @@ function uefi_linux_menu_func { 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 @@ -194,6 +237,24 @@ function uefi_linux_menu_func { 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} @@ -204,7 +265,7 @@ function uefi_linux_menu_func { boot else echo "chain empty failed" - sleep 5 + ventoy_pause fi } @@ -232,6 +293,7 @@ function uefi_iso_menu_func { set ventoy_fs_probe=udf else set ventoy_fs_probe=iso9660 + vt_iso9660_nojoliet 0 fi loopback loop ${1}${chosen_path} @@ -257,13 +319,7 @@ function uefi_iso_menu_func { 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} @@ -287,32 +343,50 @@ function uefi_iso_memdisk { 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 @@ -352,18 +426,15 @@ function legacy_linux_menu_func { 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 } @@ -381,12 +452,12 @@ function legacy_iso_menu_func { 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 @@ -399,13 +470,7 @@ function legacy_iso_menu_func { 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} @@ -446,10 +511,9 @@ function iso_unsupport_menuentry { 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 @@ -461,7 +525,7 @@ function wim_common_menuentry { boot else echo "chain empty failed" - sleep 5 + ventoy_pause fi } @@ -479,7 +543,7 @@ function wim_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.12" +set VENTOY_VERSION="1.0.13" # Default menu display mode, you can change it as you want. # 0: List mode @@ -490,10 +554,12 @@ set VTOY_DEFAULT_MENU_MODE=0 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" @@ -504,7 +570,7 @@ fi 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) @@ -512,13 +578,19 @@ if [ "$vtoy_dev" = "tftp" ]; then 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 @@ -534,10 +606,10 @@ fi 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 @@ -553,7 +625,13 @@ else 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 diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index 424bb76a..44067279 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg new file mode 100644 index 00000000..e9893e46 --- /dev/null +++ b/INSTALL/grub/localboot.cfg @@ -0,0 +1,57 @@ + +if [ "$grub_platform" = "pc" ]; then + menuentry 'Search and boot Windows' { + if search -n -s -f /bootmgr; then + ntldr /bootmgr + elif search -n -s -f /ntldr; then + ntldr /ntldr + else + echo "Windows NOT found ..." + fi + } + + menuentry 'Boot the 1st local disk' { + set root=(hd0,1) + chainloader +1 + boot + } + + menuentry 'Boot the 2nd local disk' { + set root=(hd1,1) + chainloader +1 + boot + } + + menuentry 'Boot the 3rd local disk' { + set root=(hd2,1) + chainloader +1 + boot + } + +else + + menuentry 'Search and boot Windows' { + if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then + terminal_output console + chainloader /EFI/Microsoft/Boot/bootmgfw.efi + boot + else + echo "Windows NOT found ..." + fi + } + + menuentry 'Search and boot BOOTX64.EFI' { + if search -n -s -f /efi/boot/bootx64.efi; then + terminal_output console + chainloader /efi/boot/bootx64.efi + boot + else + echo "BOOTX64.EFI NOT found ..." + fi + } + +fi + +menuentry 'Return to menu [Esc]' VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg index daecd666..a07f278d 100644 --- a/INSTALL/grub/power.cfg +++ b/INSTALL/grub/power.cfg @@ -7,7 +7,7 @@ menuentry Reboot { menuentry Halt { echo -e '\n\nSystem is halting ... \n' sleep 1 - reboot + halt } menuentry 'Return to menu [Esc]' VTOY_RET { diff --git a/INSTALL/grub/themes/ventoy/background.png b/INSTALL/grub/themes/ventoy/background.png index 10098dd3..b0190fc6 100644 Binary files a/INSTALL/grub/themes/ventoy/background.png and b/INSTALL/grub/themes/ventoy/background.png differ diff --git a/INSTALL/grub/themes/ventoy/theme.txt b/INSTALL/grub/themes/ventoy/theme.txt index a73017b7..ecb2e62b 100644 --- a/INSTALL/grub/themes/ventoy/theme.txt +++ b/INSTALL/grub/themes/ventoy/theme.txt @@ -1,9 +1,7 @@ desktop-image: "background.png" title-text: " " -title-font: "ascii" title-color: "#ffffff" -message-font: "ascii" message-color: "#f2f2f2" terminal-box: "terminal_box_*.png" @@ -16,14 +14,12 @@ 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" @@ -67,8 +63,8 @@ terminal-box: "terminal_box_*.png" + hbox{ - left = 90% - top = 30 + left = 30% + top = 95%-50 width = 10% height = 25 + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod index 19e42a99..0f6b368a 100644 Binary files a/INSTALL/grub/x86_64-efi/normal.mod and b/INSTALL/grub/x86_64-efi/normal.mod differ diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index 80dea30a..a9fc9a88 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -278,7 +278,7 @@ EOF 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 diff --git a/INSTALL/ventoy/ipxe.krn b/INSTALL/ventoy/ipxe.krn index 5b13a0e1..766971d4 100644 Binary files a/INSTALL/ventoy/ipxe.krn and b/INSTALL/ventoy/ipxe.krn differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index a45afff7..74886bb5 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi index 8f94a70d..c59a5d74 100644 Binary files a/INSTALL/ventoy/ventoy_x64.efi and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index 04761062..cc54475c 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 698d816e..9273282e 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c index f113b363..d3ccb2b4 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c @@ -33,6 +33,8 @@ ventoy_img_chunk *g_chunk; 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; @@ -42,6 +44,14 @@ uint32_t g_virt_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 ) @@ -195,6 +205,17 @@ static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned lon memcpy((char *)databuffer, override_data + start - override_start, override_end - start); } } + + 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: @@ -202,6 +223,59 @@ 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; @@ -223,6 +297,12 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun ix86 = (struct i386_all_regs *)sandev->x86_regptr; + /* 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) { @@ -384,6 +464,8 @@ static void ventoy_dump_chain(ventoy_chain_head *chain) printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size); printf("os_param->vtoy_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(); @@ -489,6 +571,14 @@ int ventoy_boot_vdisk(void *data) 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; diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h index 81be2d75..27b4dcaf 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h @@ -80,6 +80,14 @@ typedef struct ventoy_os_param 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 diff --git a/vtoyjump/vtoyjump/vtoyjump.c b/vtoyjump/vtoyjump/vtoyjump.c index ffc31210..0ee4ae46 100644 --- a/vtoyjump/vtoyjump/vtoyjump.c +++ b/vtoyjump/vtoyjump/vtoyjump.c @@ -492,13 +492,13 @@ static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) 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) @@ -724,7 +724,7 @@ static int ProcessUnattendedInstallation(const char *script) { Letter = 'X'; } - + sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter); Log("Copy file <%s> --> <%s>", script, CurDir); CopyFile(script, CurDir, FALSE);