mirror of
				https://github.com/ventoy/Ventoy.git
				synced 2025-10-29 15:55:04 -04:00 
			
		
		
		
	1.0.13 release
This commit is contained in:
		
							parent
							
								
									785255b65f
								
							
						
					
					
						commit
						a5c706511b
					
				| @ -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   | ||||
|     | ||||
|  | ||||
| @ -36,34 +36,24 @@ | ||||
| #include <Protocol/SimpleFileSystem.h> | ||||
| #include <Ventoy.h> | ||||
| 
 | ||||
| UINTN g_iso_buf_size = 0; | ||||
| BOOLEAN gMemdiskMode = FALSE; | ||||
| BOOLEAN gDebugPrint = FALSE; | ||||
| BOOLEAN gLoadIsoEfi = FALSE; | ||||
| ventoy_ram_disk g_ramdisk_param; | ||||
| ventoy_chain_head *g_chain; | ||||
| ventoy_img_chunk *g_chunk; | ||||
| UINT8 *g_os_param_reserved; | ||||
| UINT32 g_img_chunk_num; | ||||
| ventoy_override_chunk *g_override_chunk; | ||||
| UINT32 g_override_chunk_num; | ||||
| ventoy_virt_chunk *g_virt_chunk; | ||||
| UINT32 g_virt_chunk_num; | ||||
| vtoy_block_data gBlockData; | ||||
| ventoy_sector_flag *g_sector_flag = NULL; | ||||
| UINT32 g_sector_flag_num = 0; | ||||
| static grub_env_get_pf grub_env_get = NULL; | ||||
| 
 | ||||
| EFI_FILE_OPEN g_original_fopen = NULL; | ||||
| EFI_FILE_CLOSE g_original_fclose = NULL; | ||||
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL; | ||||
| 
 | ||||
| ventoy_grub_param_file_replace *g_file_replace_list = NULL; | ||||
| ventoy_efi_file_replace g_efi_file_replace; | ||||
| 
 | ||||
| CHAR16 gFirstTryBootFile[256] = {0}; | ||||
| 
 | ||||
| CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH; | ||||
| 
 | ||||
| /* Boot filename */ | ||||
| UINTN gBootFileStartIndex = 1; | ||||
| CONST CHAR16 *gEfiBootFileName[] =  | ||||
| @ -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,6 +217,70 @@ static void EFIAPI ventoy_dump_chain(ventoy_chain_head *chain) | ||||
|     ventoy_dump_virt_chunk(chain); | ||||
| } | ||||
| 
 | ||||
| static int ventoy_update_image_location(ventoy_os_param *param) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     UINT8 chksum = 0; | ||||
|     unsigned int i; | ||||
|     unsigned int length; | ||||
|     UINTN address = 0; | ||||
|     void *buffer = NULL; | ||||
|     ventoy_image_location *location = NULL; | ||||
|     ventoy_image_disk_region *region = NULL; | ||||
|     ventoy_img_chunk *chunk = g_chunk; | ||||
| 
 | ||||
|     length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region); | ||||
| 
 | ||||
|     Status = gBS->AllocatePool(EfiRuntimeServicesData, length + 4096 * 2, &buffer); | ||||
|     if (EFI_ERROR(Status) || NULL == buffer) | ||||
|     { | ||||
|         debug("Failed to allocate runtime pool %r\n", Status); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     address = (UINTN)buffer; | ||||
| 
 | ||||
|     if (address % 4096) | ||||
|     { | ||||
|         address += 4096 - (address % 4096); | ||||
|     } | ||||
| 
 | ||||
|     param->chksum = 0; | ||||
|     param->vtoy_img_location_addr = address; | ||||
|     param->vtoy_img_location_len = length; | ||||
| 
 | ||||
|     /* update check sum */ | ||||
|     for (i = 0; i < sizeof(ventoy_os_param); i++) | ||||
|     { | ||||
|         chksum += *((UINT8 *)param + i); | ||||
|     } | ||||
|     param->chksum = (chksum == 0) ? 0 : (UINT8)(0x100 - chksum); | ||||
| 
 | ||||
|     location = (ventoy_image_location *)(unsigned long)(param->vtoy_img_location_addr); | ||||
|     if (NULL == location) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     CopyMem(&location->guid, ¶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; | ||||
| } | ||||
| 
 | ||||
| EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath) | ||||
| { | ||||
|     EFI_HANDLE Handle = NULL; | ||||
| @ -258,280 +315,6 @@ EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath | ||||
|     return Handle; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_reset  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN BOOLEAN                        ExtendedVerification | ||||
| )  | ||||
| { | ||||
|     (VOID)This; | ||||
|     (VOID)ExtendedVerification; | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector | ||||
| ( | ||||
|     IN UINT64                 Sector, | ||||
|     IN UINTN                  Count, | ||||
|     OUT VOID                 *Buffer | ||||
| ) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     EFI_LBA MapLba = 0; | ||||
|     UINT32 i = 0; | ||||
|     UINTN secLeft = 0; | ||||
|     UINTN secRead = 0; | ||||
|     UINT64 ReadStart = 0; | ||||
|     UINT64 ReadEnd = 0; | ||||
|     UINT64 OverrideStart = 0; | ||||
|     UINT64 OverrideEnd= 0; | ||||
|     UINT8 *pCurBuf = (UINT8 *)Buffer; | ||||
|     ventoy_img_chunk *pchunk = g_chunk; | ||||
|     ventoy_override_chunk *pOverride = g_override_chunk; | ||||
|     EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; | ||||
| 
 | ||||
|     debug("read iso sector %lu  count %u", Sector, Count); | ||||
| 
 | ||||
|     ReadStart = Sector * 2048; | ||||
|     ReadEnd = (Sector + Count) * 2048; | ||||
| 
 | ||||
|     for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++) | ||||
|     { | ||||
|         if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector) | ||||
|         { | ||||
|             if (g_chain->disk_sector_size == 512) | ||||
|             { | ||||
|                 MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector; | ||||
|             } | ||||
| 
 | ||||
|             secLeft = pchunk->img_end_sector + 1 - Sector; | ||||
|             secRead = (Count < secLeft) ? Count : secLeft; | ||||
| 
 | ||||
|             Status = pRawBlockIo->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, | ||||
|                                      MapLba, secRead * 2048, pCurBuf); | ||||
|             if (EFI_ERROR(Status)) | ||||
|             { | ||||
|                 debug("Raw disk read block failed %r", Status); | ||||
|                 return Status; | ||||
|             } | ||||
| 
 | ||||
|             Count -= secRead; | ||||
|             Sector += secRead; | ||||
|             pCurBuf += secRead * 2048; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (ReadStart > g_chain->real_img_size_in_bytes) | ||||
|     { | ||||
|         return EFI_SUCCESS; | ||||
|     } | ||||
| 
 | ||||
|     /* override data */ | ||||
|     pCurBuf = (UINT8 *)Buffer; | ||||
|     for (i = 0; i < g_override_chunk_num; i++, pOverride++) | ||||
|     { | ||||
|         OverrideStart = pOverride->img_offset; | ||||
|         OverrideEnd = pOverride->img_offset + pOverride->override_size; | ||||
|      | ||||
|         if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (ReadStart <= OverrideStart) | ||||
|         { | ||||
|             if (ReadEnd <= OverrideEnd) | ||||
|             { | ||||
|                 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);   | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (ReadEnd <= OverrideEnd) | ||||
|             { | ||||
|                 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);      | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return EFI_SUCCESS;     | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     OUT VOID                          *Buffer | ||||
| )  | ||||
| { | ||||
|     //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
 | ||||
| 
 | ||||
|     (VOID)This; | ||||
|     (VOID)MediaId; | ||||
| 
 | ||||
|     CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize); | ||||
| 
 | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_read  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     OUT VOID                          *Buffer | ||||
| )  | ||||
| { | ||||
|     UINT32 i = 0; | ||||
|     UINT32 j = 0; | ||||
|     UINT32 lbacount = 0; | ||||
|     UINT32 secNum = 0; | ||||
|     UINT64 offset = 0; | ||||
|     EFI_LBA curlba = 0; | ||||
|     EFI_LBA lastlba = 0; | ||||
|     UINT8 *lastbuffer; | ||||
|     ventoy_sector_flag *cur_flag; | ||||
|     ventoy_virt_chunk *node; | ||||
|      | ||||
|     //debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
 | ||||
| 
 | ||||
|     secNum = BufferSize / 2048; | ||||
|     offset = Lba * 2048; | ||||
| 
 | ||||
|     if (offset + BufferSize <= g_chain->real_img_size_in_bytes) | ||||
|     { | ||||
|         return ventoy_read_iso_sector(Lba, secNum, Buffer); | ||||
|     } | ||||
| 
 | ||||
|     if (secNum > g_sector_flag_num) | ||||
|     { | ||||
|         cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag)); | ||||
|         if (NULL == cur_flag) | ||||
|         { | ||||
|             return EFI_OUT_OF_RESOURCES; | ||||
|         } | ||||
| 
 | ||||
|         FreePool(g_sector_flag); | ||||
|         g_sector_flag = cur_flag; | ||||
|         g_sector_flag_num = secNum; | ||||
|     } | ||||
| 
 | ||||
|     for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) | ||||
|     { | ||||
|         cur_flag->flag = 0; | ||||
|         for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++) | ||||
|         { | ||||
|             if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end) | ||||
|             { | ||||
|                 CopyMem((UINT8 *)Buffer + j * 2048,  | ||||
|                        (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048, | ||||
|                        2048); | ||||
|                 cur_flag->flag = 1; | ||||
|                 break; | ||||
|             } | ||||
|             else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end) | ||||
|             { | ||||
|                 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start; | ||||
|                 cur_flag->flag = 2; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) | ||||
|     { | ||||
|         if (cur_flag->flag == 2) | ||||
|         { | ||||
|             if (lastlba == 0) | ||||
|             { | ||||
|                 lastbuffer = (UINT8 *)Buffer + j * 2048; | ||||
|                 lastlba = cur_flag->remap_lba; | ||||
|                 lbacount = 1; | ||||
|             } | ||||
|             else if (lastlba + lbacount == cur_flag->remap_lba) | ||||
|             { | ||||
|                 lbacount++; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); | ||||
|                 lastbuffer = (UINT8 *)Buffer + j * 2048; | ||||
|                 lastlba = cur_flag->remap_lba; | ||||
|                 lbacount = 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (lbacount > 0) | ||||
|     { | ||||
|         ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); | ||||
|     } | ||||
| 
 | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_write  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     IN VOID                           *Buffer | ||||
| )  | ||||
| { | ||||
|     (VOID)This; | ||||
|     (VOID)MediaId; | ||||
|     (VOID)Lba; | ||||
|     (VOID)BufferSize; | ||||
|     (VOID)Buffer; | ||||
| 	return EFI_WRITE_PROTECTED; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) | ||||
| { | ||||
| 	(VOID)This; | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_fill_device_path(VOID) | ||||
| { | ||||
|     UINTN NameLen = 0; | ||||
|     UINT8 TmpBuf[128] = {0}; | ||||
|     VENDOR_DEVICE_PATH *venPath = NULL; | ||||
| 
 | ||||
|     venPath = (VENDOR_DEVICE_PATH *)TmpBuf; | ||||
|     NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME); | ||||
|     venPath->Header.Type = HARDWARE_DEVICE_PATH; | ||||
|     venPath->Header.SubType = HW_VENDOR_DP; | ||||
|     venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; | ||||
|     venPath->Header.Length[1] = 0; | ||||
|     CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID)); | ||||
|     CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen); | ||||
|      | ||||
|     gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); | ||||
|     gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; | ||||
| 
 | ||||
|     debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE)); | ||||
| 
 | ||||
|     return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
| @ -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; | ||||
|     FreePool(g_sector_flag); | ||||
|     g_sector_flag_num = 0; | ||||
| 
 | ||||
|     Status = g_original_fopen(This, New, Name, Mode, Attributes); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     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) | ||||
|     { | ||||
|         return Status; | ||||
|         FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr); | ||||
|     } | ||||
| 
 | ||||
|     if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC && | ||||
|         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; | ||||
|     return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_wrapper_open_volume | ||||
| ( | ||||
|     IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *This, | ||||
|     OUT EFI_FILE_PROTOCOL                 **Root | ||||
| ) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|      | ||||
|     Status = g_original_open_volume(This, Root); | ||||
|     if (!EFI_ERROR(Status)) | ||||
|     { | ||||
|         g_original_fopen = (*Root)->Open; | ||||
|         g_original_fclose = (*Root)->Close; | ||||
|         (*Root)->Open = ventoy_wrapper_file_open; | ||||
|     } | ||||
| 
 | ||||
|     return Status; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) | ||||
| { | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -29,6 +29,7 @@ | ||||
|   Ventoy.h | ||||
|   Ventoy.c | ||||
|   VentoyDebug.c | ||||
|   VentoyProtocol.c | ||||
| 
 | ||||
| [Packages] | ||||
|   MdePkg/MdePkg.dec | ||||
|  | ||||
| @ -0,0 +1,631 @@ | ||||
| /******************************************************************************
 | ||||
|  * Ventoy.c | ||||
|  * | ||||
|  * Copyright (c) 2020, longpanda <admin@ventoy.net> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include <Uefi.h> | ||||
| #include <Library/DebugLib.h> | ||||
| #include <Library/PrintLib.h> | ||||
| #include <Library/UefiLib.h> | ||||
| #include <Library/BaseMemoryLib.h> | ||||
| #include <Library/DevicePathLib.h> | ||||
| #include <Library/MemoryAllocationLib.h> | ||||
| #include <Library/UefiBootServicesTableLib.h> | ||||
| #include <Library/UefiRuntimeServicesTableLib.h> | ||||
| #include <Library/UefiApplicationEntryPoint.h> | ||||
| #include <Protocol/LoadedImage.h> | ||||
| #include <Guid/FileInfo.h> | ||||
| #include <Guid/FileSystemInfo.h> | ||||
| #include <Protocol/BlockIo.h> | ||||
| #include <Protocol/RamDisk.h> | ||||
| #include <Protocol/SimpleFileSystem.h> | ||||
| #include <Ventoy.h> | ||||
| 
 | ||||
| UINTN g_iso_buf_size = 0; | ||||
| BOOLEAN gMemdiskMode = FALSE; | ||||
| 
 | ||||
| ventoy_sector_flag *g_sector_flag = NULL; | ||||
| UINT32 g_sector_flag_num = 0; | ||||
| 
 | ||||
| EFI_FILE_OPEN g_original_fopen = NULL; | ||||
| EFI_FILE_CLOSE g_original_fclose = NULL; | ||||
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL; | ||||
| 
 | ||||
| /* EFI block device vendor device path GUID */ | ||||
| EFI_GUID gVtoyBlockDevicePathGuid = VTOY_BLOCK_DEVICE_PATH_GUID; | ||||
| 
 | ||||
| #define VENTOY_ISO9660_SECTOR_OVERFLOW  2097152 | ||||
| 
 | ||||
| BOOLEAN g_fixup_iso9660_secover_enable = FALSE; | ||||
| BOOLEAN g_fixup_iso9660_secover_start  = FALSE; | ||||
| UINT64  g_fixup_iso9660_secover_1st_secs = 0; | ||||
| UINT64  g_fixup_iso9660_secover_cur_secs = 0; | ||||
| UINT64  g_fixup_iso9660_secover_tot_secs = 0; | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_reset  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN BOOLEAN                        ExtendedVerification | ||||
| )  | ||||
| { | ||||
|     (VOID)This; | ||||
|     (VOID)ExtendedVerification; | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector | ||||
| ( | ||||
|     IN UINT64                 Sector, | ||||
|     IN UINTN                  Count, | ||||
|     OUT VOID                 *Buffer | ||||
| ) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     EFI_LBA MapLba = 0; | ||||
|     UINT32 i = 0; | ||||
|     UINTN secLeft = 0; | ||||
|     UINTN secRead = 0; | ||||
|     UINT64 ReadStart = 0; | ||||
|     UINT64 ReadEnd = 0; | ||||
|     UINT64 OverrideStart = 0; | ||||
|     UINT64 OverrideEnd= 0; | ||||
|     UINT8 *pCurBuf = (UINT8 *)Buffer; | ||||
|     ventoy_img_chunk *pchunk = g_chunk; | ||||
|     ventoy_override_chunk *pOverride = g_override_chunk; | ||||
|     EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; | ||||
|      | ||||
|     debug("read iso sector %lu  count %u", Sector, Count); | ||||
| 
 | ||||
|     ReadStart = Sector * 2048; | ||||
|     ReadEnd = (Sector + Count) * 2048; | ||||
| 
 | ||||
|     for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++) | ||||
|     { | ||||
|         if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector) | ||||
|         { | ||||
|             if (g_chain->disk_sector_size == 512) | ||||
|             { | ||||
|                 MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector; | ||||
|             } | ||||
| 
 | ||||
|             secLeft = pchunk->img_end_sector + 1 - Sector; | ||||
|             secRead = (Count < secLeft) ? Count : secLeft; | ||||
| 
 | ||||
|             Status = pRawBlockIo->ReadBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, | ||||
|                                      MapLba, secRead * 2048, pCurBuf); | ||||
|             if (EFI_ERROR(Status)) | ||||
|             { | ||||
|                 debug("Raw disk read block failed %r", Status); | ||||
|                 return Status; | ||||
|             } | ||||
| 
 | ||||
|             Count -= secRead; | ||||
|             Sector += secRead; | ||||
|             pCurBuf += secRead * 2048; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (ReadStart > g_chain->real_img_size_in_bytes) | ||||
|     { | ||||
|         return EFI_SUCCESS; | ||||
|     } | ||||
| 
 | ||||
|     /* override data */ | ||||
|     pCurBuf = (UINT8 *)Buffer; | ||||
|     for (i = 0; i < g_override_chunk_num; i++, pOverride++) | ||||
|     { | ||||
|         OverrideStart = pOverride->img_offset; | ||||
|         OverrideEnd = pOverride->img_offset + pOverride->override_size; | ||||
|      | ||||
|         if (OverrideStart >= ReadEnd || ReadStart >= OverrideEnd) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (ReadStart <= OverrideStart) | ||||
|         { | ||||
|             if (ReadEnd <= OverrideEnd) | ||||
|             { | ||||
|                 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, ReadEnd - OverrideStart);   | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 CopyMem(pCurBuf + OverrideStart - ReadStart, pOverride->override_data, pOverride->override_size); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (ReadEnd <= OverrideEnd) | ||||
|             { | ||||
|                 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, ReadEnd - ReadStart);  | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 CopyMem(pCurBuf, pOverride->override_data + ReadStart - OverrideStart, OverrideEnd - ReadStart); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) &&  | ||||
|             pOverride->override_size == sizeof(ventoy_iso9660_override)) | ||||
|         { | ||||
|             ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)pOverride->override_data; | ||||
|             if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW) | ||||
|             { | ||||
|                 g_fixup_iso9660_secover_start = TRUE; | ||||
|                 g_fixup_iso9660_secover_cur_secs = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return EFI_SUCCESS;     | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     OUT VOID                          *Buffer | ||||
| )  | ||||
| { | ||||
|     //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
 | ||||
| 
 | ||||
|     (VOID)This; | ||||
|     (VOID)MediaId; | ||||
| 
 | ||||
|     CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize); | ||||
| 
 | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_LBA EFIAPI ventoy_fixup_iso9660_sector(IN EFI_LBA Lba, UINT32 secNum) | ||||
| { | ||||
|     UINT32 i = 0; | ||||
| 
 | ||||
|     if (g_fixup_iso9660_secover_cur_secs > 0) | ||||
|     { | ||||
|         Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; | ||||
|         g_fixup_iso9660_secover_cur_secs += secNum; | ||||
|         if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) | ||||
|         { | ||||
|             g_fixup_iso9660_secover_start = FALSE; | ||||
|             goto end; | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         ventoy_iso9660_override *dirent; | ||||
|         ventoy_override_chunk *pOverride; | ||||
| 
 | ||||
|         for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) | ||||
|         { | ||||
|             dirent = (ventoy_iso9660_override *)pOverride->override_data; | ||||
|             if (Lba == dirent->first_sector) | ||||
|             { | ||||
|                 g_fixup_iso9660_secover_start = FALSE; | ||||
|                 goto end; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (g_fixup_iso9660_secover_start) | ||||
|         { | ||||
|             for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++) | ||||
|             { | ||||
|                 dirent = (ventoy_iso9660_override *)pOverride->override_data; | ||||
|                 if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector) | ||||
|                 { | ||||
|                     g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048; | ||||
|                     g_fixup_iso9660_secover_cur_secs = secNum; | ||||
|                     if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs) | ||||
|                     { | ||||
|                         g_fixup_iso9660_secover_start = FALSE; | ||||
|                     } | ||||
|                     Lba += VENTOY_ISO9660_SECTOR_OVERFLOW; | ||||
|                     goto end; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| end: | ||||
|     return Lba; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_read  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     OUT VOID                          *Buffer | ||||
| )  | ||||
| { | ||||
|     UINT32 i = 0; | ||||
|     UINT32 j = 0; | ||||
|     UINT32 lbacount = 0; | ||||
|     UINT32 secNum = 0; | ||||
|     UINT64 offset = 0; | ||||
|     EFI_LBA curlba = 0; | ||||
|     EFI_LBA lastlba = 0; | ||||
|     UINT8 *lastbuffer; | ||||
|     ventoy_sector_flag *cur_flag; | ||||
|     ventoy_virt_chunk *node; | ||||
|      | ||||
|     //debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
 | ||||
| 
 | ||||
|     secNum = BufferSize / 2048; | ||||
| 
 | ||||
|     /* Workaround for SSTR PE loader error */ | ||||
|     if (g_fixup_iso9660_secover_start) | ||||
|     { | ||||
|         Lba = ventoy_fixup_iso9660_sector(Lba, secNum); | ||||
|     } | ||||
| 
 | ||||
|     offset = Lba * 2048; | ||||
| 
 | ||||
|     if (offset + BufferSize <= g_chain->real_img_size_in_bytes) | ||||
|     { | ||||
|         return ventoy_read_iso_sector(Lba, secNum, Buffer); | ||||
|     } | ||||
| 
 | ||||
|     if (secNum > g_sector_flag_num) | ||||
|     { | ||||
|         cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag)); | ||||
|         if (NULL == cur_flag) | ||||
|         { | ||||
|             return EFI_OUT_OF_RESOURCES; | ||||
|         } | ||||
| 
 | ||||
|         FreePool(g_sector_flag); | ||||
|         g_sector_flag = cur_flag; | ||||
|         g_sector_flag_num = secNum; | ||||
|     } | ||||
| 
 | ||||
|     for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) | ||||
|     { | ||||
|         cur_flag->flag = 0; | ||||
|         for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++) | ||||
|         { | ||||
|             if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end) | ||||
|             { | ||||
|                 CopyMem((UINT8 *)Buffer + j * 2048,  | ||||
|                        (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048, | ||||
|                        2048); | ||||
|                 cur_flag->flag = 1; | ||||
|                 break; | ||||
|             } | ||||
|             else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end) | ||||
|             { | ||||
|                 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start; | ||||
|                 cur_flag->flag = 2; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (curlba = Lba, cur_flag = g_sector_flag, j = 0; j < secNum; j++, curlba++, cur_flag++) | ||||
|     { | ||||
|         if (cur_flag->flag == 2) | ||||
|         { | ||||
|             if (lastlba == 0) | ||||
|             { | ||||
|                 lastbuffer = (UINT8 *)Buffer + j * 2048; | ||||
|                 lastlba = cur_flag->remap_lba; | ||||
|                 lbacount = 1; | ||||
|             } | ||||
|             else if (lastlba + lbacount == cur_flag->remap_lba) | ||||
|             { | ||||
|                 lbacount++; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); | ||||
|                 lastbuffer = (UINT8 *)Buffer + j * 2048; | ||||
|                 lastlba = cur_flag->remap_lba; | ||||
|                 lbacount = 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (lbacount > 0) | ||||
|     { | ||||
|         ventoy_read_iso_sector(lastlba, lbacount, lastbuffer); | ||||
|     } | ||||
| 
 | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_write  | ||||
| ( | ||||
|     IN EFI_BLOCK_IO_PROTOCOL          *This, | ||||
|     IN UINT32                          MediaId, | ||||
|     IN EFI_LBA                         Lba, | ||||
|     IN UINTN                           BufferSize, | ||||
|     IN VOID                           *Buffer | ||||
| )  | ||||
| { | ||||
|     (VOID)This; | ||||
|     (VOID)MediaId; | ||||
|     (VOID)Lba; | ||||
|     (VOID)BufferSize; | ||||
|     (VOID)Buffer; | ||||
| 	return EFI_WRITE_PROTECTED; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) | ||||
| { | ||||
| 	(VOID)This; | ||||
| 	return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_fill_device_path(VOID) | ||||
| { | ||||
|     UINTN NameLen = 0; | ||||
|     UINT8 TmpBuf[128] = {0}; | ||||
|     VENDOR_DEVICE_PATH *venPath = NULL; | ||||
| 
 | ||||
|     venPath = (VENDOR_DEVICE_PATH *)TmpBuf; | ||||
|     NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME); | ||||
|     venPath->Header.Type = HARDWARE_DEVICE_PATH; | ||||
|     venPath->Header.SubType = HW_VENDOR_DP; | ||||
|     venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; | ||||
|     venPath->Header.Length[1] = 0; | ||||
|     CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID)); | ||||
|     CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen); | ||||
|      | ||||
|     gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); | ||||
|     gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; | ||||
| 
 | ||||
|     debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE)); | ||||
| 
 | ||||
|     return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName) | ||||
| { | ||||
|     UINTN i = 0; | ||||
|     UINTN Count = 0; | ||||
|     CHAR16 *DriverName = NULL; | ||||
|     EFI_HANDLE *Handles = NULL; | ||||
|     EFI_HANDLE DrvHandles[2] = { NULL }; | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; | ||||
|     EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; | ||||
| 
 | ||||
|     debug("ventoy_connect_driver <%s>...", DrvName); | ||||
| 
 | ||||
|     Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid,  | ||||
|                                      NULL, &Count, &Handles); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     { | ||||
|         return Status; | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < Count; i++) | ||||
|     { | ||||
|         Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); | ||||
|         if (EFI_ERROR(Status)) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName); | ||||
|         if (EFI_ERROR(Status) || NULL == DriverName) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (StrStr(DriverName, DrvName)) | ||||
|         { | ||||
|             debug("Find driver name2:<%s>: <%s>", DriverName, DrvName); | ||||
|             DrvHandles[0] = Handles[i]; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (i < Count) | ||||
|     { | ||||
|         Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); | ||||
|         debug("Connect partition driver:<%r>", Status); | ||||
|         goto end; | ||||
|     } | ||||
| 
 | ||||
|     debug("%s NOT found, now try COMPONENT_NAME", DrvName); | ||||
| 
 | ||||
|     Count = 0; | ||||
|     FreePool(Handles); | ||||
|     Handles = NULL; | ||||
| 
 | ||||
|     Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid,  | ||||
|                                      NULL, &Count, &Handles); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     { | ||||
|         return Status; | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < Count; i++) | ||||
|     { | ||||
|         Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); | ||||
|         if (EFI_ERROR(Status)) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName); | ||||
|         if (EFI_ERROR(Status)) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (StrStr(DriverName, DrvName)) | ||||
|         { | ||||
|             debug("Find driver name:<%s>: <%s>", DriverName, DrvName); | ||||
|             DrvHandles[0] = Handles[i]; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (i < Count) | ||||
|     { | ||||
|         Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); | ||||
|         debug("Connect partition driver:<%r>", Status); | ||||
|         goto end; | ||||
|     } | ||||
| 
 | ||||
|     Status = EFI_NOT_FOUND; | ||||
|      | ||||
| end: | ||||
|     FreePool(Handles); | ||||
|      | ||||
|     return Status; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) | ||||
| {    | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo); | ||||
|      | ||||
|     ventoy_fill_device_path(); | ||||
|      | ||||
|     gBlockData.Media.BlockSize = 2048; | ||||
|     gBlockData.Media.LastBlock = ImgSize / 2048 - 1; | ||||
|     gBlockData.Media.ReadOnly = TRUE; | ||||
|     gBlockData.Media.MediaPresent = 1; | ||||
|     gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; | ||||
| 
 | ||||
| 	pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; | ||||
| 	pBlockIo->Media = &(gBlockData.Media); | ||||
| 	pBlockIo->Reset = ventoy_block_io_reset; | ||||
|     pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; | ||||
| 	pBlockIo->WriteBlocks = ventoy_block_io_write; | ||||
| 	pBlockIo->FlushBlocks = ventoy_block_io_flush; | ||||
| 
 | ||||
|     Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle, | ||||
|             &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo, | ||||
|             &gEfiDevicePathProtocolGuid, gBlockData.Path, | ||||
|             NULL); | ||||
|     debug("Install protocol %r %p", Status, gBlockData.Handle); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     { | ||||
|         return Status; | ||||
|     } | ||||
|      | ||||
|     Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver"); | ||||
|     debug("Connect disk IO driver %r", Status); | ||||
|     ventoy_debug_pause(); | ||||
|      | ||||
|     Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver"); | ||||
|     debug("Connect partition driver %r", Status); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     { | ||||
|         Status = gBS->ConnectController(gBlockData.Handle, NULL, NULL, TRUE); | ||||
|         debug("Connect all controller %r", Status); | ||||
|     } | ||||
| 
 | ||||
|     ventoy_debug_pause(); | ||||
| 
 | ||||
|     return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_wrapper_file_open | ||||
| ( | ||||
|     EFI_FILE_HANDLE This,  | ||||
|     EFI_FILE_HANDLE *New, | ||||
|     CHAR16 *Name,  | ||||
|     UINT64 Mode,  | ||||
|     UINT64 Attributes | ||||
| ) | ||||
| { | ||||
|     UINT32 i = 0; | ||||
|     UINT32 j = 0; | ||||
|     UINT64 Sectors = 0; | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|     CHAR8 TmpName[256]; | ||||
|     ventoy_virt_chunk *virt = NULL; | ||||
| 
 | ||||
|     Status = g_original_fopen(This, New, Name, Mode, Attributes); | ||||
|     if (EFI_ERROR(Status)) | ||||
|     { | ||||
|         return Status; | ||||
|     } | ||||
| 
 | ||||
|     if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC && | ||||
|         g_file_replace_list->new_file_virtual_id < g_virt_chunk_num) | ||||
|     { | ||||
|         AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); | ||||
|         for (j = 0; j < 4; j++) | ||||
|         { | ||||
|             if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName)) | ||||
|             { | ||||
|                 g_original_fclose(*New); | ||||
|                 *New = &g_efi_file_replace.WrapperHandle; | ||||
|                 ventoy_wrapper_file_procotol(*New); | ||||
| 
 | ||||
|                 virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id; | ||||
| 
 | ||||
|                 Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start); | ||||
|                  | ||||
|                 g_efi_file_replace.BlockIoSectorStart = virt->mem_sector_start; | ||||
|                 g_efi_file_replace.FileSizeBytes = Sectors * 2048; | ||||
| 
 | ||||
|                 if (gDebugPrint) | ||||
|                 { | ||||
|                     debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name, | ||||
|                         g_efi_file_replace.BlockIoSectorStart, Sectors, Sectors * 2048); | ||||
|                     sleep(3); | ||||
|                 } | ||||
|                  | ||||
|                 return Status; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return Status; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_wrapper_open_volume | ||||
| ( | ||||
|     IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL     *This, | ||||
|     OUT EFI_FILE_PROTOCOL                 **Root | ||||
| ) | ||||
| { | ||||
|     EFI_STATUS Status = EFI_SUCCESS; | ||||
|      | ||||
|     Status = g_original_open_volume(This, Root); | ||||
|     if (!EFI_ERROR(Status)) | ||||
|     { | ||||
|         g_original_fopen = (*Root)->Open; | ||||
|         g_original_fclose = (*Root)->Close; | ||||
|         (*Root)->Open = ventoy_wrapper_file_open; | ||||
|     } | ||||
| 
 | ||||
|     return Status; | ||||
| } | ||||
| 
 | ||||
| EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume) | ||||
| { | ||||
|     g_original_open_volume = OpenVolume; | ||||
|     return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										491
									
								
								GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										491
									
								
								GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,491 @@ | ||||
| /* test.c -- The test command..  */ | ||||
| /*
 | ||||
|  *  GRUB  --  GRand Unified Bootloader | ||||
|  *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc. | ||||
|  * | ||||
|  *  GRUB is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  GRUB is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include <grub/dl.h> | ||||
| #include <grub/misc.h> | ||||
| #include <grub/mm.h> | ||||
| #include <grub/env.h> | ||||
| #include <grub/fs.h> | ||||
| #include <grub/device.h> | ||||
| #include <grub/file.h> | ||||
| #include <grub/command.h> | ||||
| #include <grub/i18n.h> | ||||
| 
 | ||||
| GRUB_MOD_LICENSE ("GPLv3+"); | ||||
| 
 | ||||
| static int g_test_case_insensitive = 0; | ||||
| 
 | ||||
| /* A simple implementation for signed numbers. */ | ||||
| static int | ||||
| grub_strtosl (char *arg, char **end, int base) | ||||
| { | ||||
|   if (arg[0] == '-') | ||||
|     return -grub_strtoul (arg + 1, end, base); | ||||
|   return grub_strtoul (arg, end, base); | ||||
| } | ||||
| 
 | ||||
| /* Context for test_parse.  */ | ||||
| struct test_parse_ctx | ||||
| { | ||||
|   int invert; | ||||
|   int or, and; | ||||
|   int file_exists; | ||||
|   struct grub_dirhook_info file_info; | ||||
|   char *filename; | ||||
| }; | ||||
| 
 | ||||
| /* Take care of discarding and inverting. */ | ||||
| static void | ||||
| update_val (int val, struct test_parse_ctx *ctx) | ||||
| { | ||||
|   ctx->and = ctx->and && (ctx->invert ? ! val : val); | ||||
|   ctx->invert = 0; | ||||
| } | ||||
| 
 | ||||
| /* A hook for iterating directories. */ | ||||
| static int | ||||
| find_file (const char *cur_filename, const struct grub_dirhook_info *info, | ||||
| 	   void *data) | ||||
| { | ||||
|   int case_insensitive = 0; | ||||
|   struct test_parse_ctx *ctx = data; | ||||
| 
 | ||||
|   if (g_test_case_insensitive || info->case_insensitive) | ||||
|     case_insensitive = 1; | ||||
| 
 | ||||
|   if ((case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename) | ||||
|        : grub_strcmp (cur_filename, ctx->filename)) == 0) | ||||
|     { | ||||
|       ctx->file_info = *info; | ||||
|       ctx->file_exists = 1; | ||||
|       return 1; | ||||
|     } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| /* Check if file exists and fetch its information. */ | ||||
| static void | ||||
| get_fileinfo (char *path, struct test_parse_ctx *ctx) | ||||
| { | ||||
|   char *pathname; | ||||
|   char *device_name; | ||||
|   grub_fs_t fs; | ||||
|   grub_device_t dev; | ||||
| 
 | ||||
|   ctx->file_exists = 0; | ||||
|   device_name = grub_file_get_device_name (path); | ||||
|   dev = grub_device_open (device_name); | ||||
|   if (! dev) | ||||
|     { | ||||
|       grub_free (device_name); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|   fs = grub_fs_probe (dev); | ||||
|   if (! fs) | ||||
|     { | ||||
|       grub_free (device_name); | ||||
|       grub_device_close (dev); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|   pathname = grub_strchr (path, ')'); | ||||
|   if (! pathname) | ||||
|     pathname = path; | ||||
|   else | ||||
|     pathname++; | ||||
| 
 | ||||
|   /* Remove trailing '/'. */ | ||||
|   while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') | ||||
|     pathname[grub_strlen (pathname) - 1] = 0; | ||||
| 
 | ||||
|   /* Split into path and filename. */ | ||||
|   ctx->filename = grub_strrchr (pathname, '/'); | ||||
|   if (! ctx->filename) | ||||
|     { | ||||
|       path = grub_strdup ("/"); | ||||
|       ctx->filename = pathname; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       ctx->filename++; | ||||
|       path = grub_strdup (pathname); | ||||
|       path[ctx->filename - pathname] = 0; | ||||
|     } | ||||
| 
 | ||||
|   /* It's the whole device. */ | ||||
|   if (! *pathname) | ||||
|     { | ||||
|       ctx->file_exists = 1; | ||||
|       grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info)); | ||||
|       /* Root is always a directory. */ | ||||
|       ctx->file_info.dir = 1; | ||||
| 
 | ||||
|       /* Fetch writing time. */ | ||||
|       ctx->file_info.mtimeset = 0; | ||||
|       if (fs->fs_mtime) | ||||
| 	{ | ||||
| 	  if (! fs->fs_mtime (dev, &ctx->file_info.mtime)) | ||||
| 	    ctx->file_info.mtimeset = 1; | ||||
| 	  grub_errno = GRUB_ERR_NONE; | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     (fs->fs_dir) (dev, path, find_file, ctx); | ||||
| 
 | ||||
|   grub_device_close (dev); | ||||
|   grub_free (path); | ||||
|   grub_free (device_name); | ||||
| } | ||||
| 
 | ||||
| /* Parse a test expression starting from *argn. */ | ||||
| static int | ||||
| test_parse (char **args, int *argn, int argc) | ||||
| { | ||||
|   struct test_parse_ctx ctx = { | ||||
|     .and = 1, | ||||
|     .or = 0, | ||||
|     .invert = 0 | ||||
|   }; | ||||
| 
 | ||||
|   /* Here we have the real parsing. */ | ||||
|   while (*argn < argc) | ||||
|     { | ||||
|       /* First try 3 argument tests. */ | ||||
|       if (*argn + 2 < argc) | ||||
| 	{ | ||||
| 	  /* String tests. */ | ||||
| 	  if (grub_strcmp (args[*argn + 1], "=") == 0 | ||||
| 	      || grub_strcmp (args[*argn + 1], "==") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "!=") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  /* GRUB extension: lexicographical sorting. */ | ||||
| 	  if (grub_strcmp (args[*argn + 1], "<") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "<=") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], ">") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], ">=") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0, | ||||
| 			  &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  /* Number tests. */ | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-eq") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 			  == grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-ge") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 			  >= grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-gt") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 			  > grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-le") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 		      <= grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-lt") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 			  < grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-ne") == 0) | ||||
| 	    { | ||||
| 	      update_val (grub_strtosl (args[*argn], 0, 0) | ||||
| 			  != grub_strtosl (args[*argn + 2], 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  /* GRUB extension: compare numbers skipping prefixes.
 | ||||
| 	     Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */ | ||||
| 	  if (grub_strcmp (args[*argn + 1], "-pgt") == 0 | ||||
| 	      || grub_strcmp (args[*argn + 1], "-plt") == 0) | ||||
| 	    { | ||||
| 	      int i; | ||||
| 	      /* Skip common prefix. */ | ||||
| 	      for (i = 0; args[*argn][i] == args[*argn + 2][i] | ||||
| 		     && args[*argn][i]; i++); | ||||
| 
 | ||||
| 	      /* Go the digits back. */ | ||||
| 	      i--; | ||||
| 	      while (grub_isdigit (args[*argn][i]) && i > 0) | ||||
| 		i--; | ||||
| 	      i++; | ||||
| 
 | ||||
| 	      if (grub_strcmp (args[*argn + 1], "-pgt") == 0) | ||||
| 		update_val (grub_strtoul (args[*argn] + i, 0, 0) | ||||
| 			    > grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); | ||||
| 	      else | ||||
| 		update_val (grub_strtoul (args[*argn] + i, 0, 0) | ||||
| 			    < grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
 | ||||
| 	     will be added to the first mtime. */ | ||||
| 	  if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0 | ||||
| 	      || grub_memcmp (args[*argn + 1], "-ot", 3) == 0) | ||||
| 	    { | ||||
| 	      struct grub_dirhook_info file1; | ||||
| 	      int file1exists; | ||||
| 	      int bias = 0; | ||||
| 
 | ||||
| 	      /* Fetch fileinfo. */ | ||||
| 	      get_fileinfo (args[*argn], &ctx); | ||||
| 	      file1 = ctx.file_info; | ||||
| 	      file1exists = ctx.file_exists; | ||||
| 	      get_fileinfo (args[*argn + 2], &ctx); | ||||
| 
 | ||||
| 	      if (args[*argn + 1][3]) | ||||
| 		bias = grub_strtosl (args[*argn + 1] + 3, 0, 0); | ||||
| 
 | ||||
| 	      if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0) | ||||
| 		update_val ((file1exists && ! ctx.file_exists) | ||||
| 			    || (file1.mtimeset && ctx.file_info.mtimeset | ||||
| 				&& file1.mtime + bias > ctx.file_info.mtime), | ||||
| 			    &ctx); | ||||
| 	      else | ||||
| 		update_val ((! file1exists && ctx.file_exists) | ||||
| 			    || (file1.mtimeset && ctx.file_info.mtimeset | ||||
| 				&& file1.mtime + bias < ctx.file_info.mtime), | ||||
| 			    &ctx); | ||||
| 	      (*argn) += 3; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 	} | ||||
| 
 | ||||
|       /* Two-argument tests. */ | ||||
|       if (*argn + 1 < argc) | ||||
| 	{ | ||||
| 	  /* File tests. */ | ||||
| 	  if (grub_strcmp (args[*argn], "-d") == 0) | ||||
| 	    { | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
| 	      update_val (ctx.file_exists && ctx.file_info.dir, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
|        | ||||
| 	  if (grub_strcmp (args[*argn], "-D") == 0) | ||||
| 	    { | ||||
| 	      g_test_case_insensitive = 1; | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
|           g_test_case_insensitive = 0; | ||||
| 	      update_val (ctx.file_exists && ctx.file_info.dir, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn], "-e") == 0) | ||||
| 	    { | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
| 	      update_val (ctx.file_exists, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
|        | ||||
| 	  if (grub_strcmp (args[*argn], "-E") == 0) | ||||
| 	    { | ||||
| 	      g_test_case_insensitive = 1; | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
|           g_test_case_insensitive = 0; | ||||
| 	      update_val (ctx.file_exists, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn], "-f") == 0) | ||||
| 	    { | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
| 	      /* FIXME: check for other types. */ | ||||
| 	      update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 	  if (grub_strcmp (args[*argn], "-F") == 0) | ||||
| 	    { | ||||
| 	      g_test_case_insensitive = 1; | ||||
| 	      get_fileinfo (args[*argn + 1], &ctx); | ||||
|           g_test_case_insensitive = 0; | ||||
| 	      /* FIXME: check for other types. */ | ||||
| 	      update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (grub_strcmp (args[*argn], "-s") == 0) | ||||
| 	    { | ||||
| 	      grub_file_t file; | ||||
| 	      file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE | ||||
| 				     | GRUB_FILE_TYPE_NO_DECOMPRESS); | ||||
| 	      update_val (file && (grub_file_size (file) != 0), &ctx); | ||||
| 	      if (file) | ||||
| 		grub_file_close (file); | ||||
| 	      grub_errno = GRUB_ERR_NONE; | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 
 | ||||
| 	  /* String tests. */ | ||||
| 	  if (grub_strcmp (args[*argn], "-n") == 0) | ||||
| 	    { | ||||
| 	      update_val (args[*argn + 1][0], &ctx); | ||||
| 
 | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 	  if (grub_strcmp (args[*argn], "-z") == 0) | ||||
| 	    { | ||||
| 	      update_val (! args[*argn + 1][0], &ctx); | ||||
| 	      (*argn) += 2; | ||||
| 	      continue; | ||||
| 	    } | ||||
| 	} | ||||
| 
 | ||||
|       /* Special modifiers. */ | ||||
| 
 | ||||
|       /* End of expression. return to parent. */ | ||||
|       if (grub_strcmp (args[*argn], ")") == 0) | ||||
| 	{ | ||||
| 	  (*argn)++; | ||||
| 	  return ctx.or || ctx.and; | ||||
| 	} | ||||
|       /* Recursively invoke if parenthesis. */ | ||||
|       if (grub_strcmp (args[*argn], "(") == 0) | ||||
| 	{ | ||||
| 	  (*argn)++; | ||||
| 	  update_val (test_parse (args, argn, argc), &ctx); | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       if (grub_strcmp (args[*argn], "!") == 0) | ||||
| 	{ | ||||
| 	  ctx.invert = ! ctx.invert; | ||||
| 	  (*argn)++; | ||||
| 	  continue; | ||||
| 	} | ||||
|       if (grub_strcmp (args[*argn], "-a") == 0) | ||||
| 	{ | ||||
| 	  (*argn)++; | ||||
| 	  continue; | ||||
| 	} | ||||
|       if (grub_strcmp (args[*argn], "-o") == 0) | ||||
| 	{ | ||||
| 	  ctx.or = ctx.or || ctx.and; | ||||
| 	  ctx.and = 1; | ||||
| 	  (*argn)++; | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       /* No test found. Interpret if as just a string. */ | ||||
|       update_val (args[*argn][0], &ctx); | ||||
|       (*argn)++; | ||||
|     } | ||||
|   return ctx.or || ctx.and; | ||||
| } | ||||
| 
 | ||||
| static grub_err_t | ||||
| grub_cmd_test (grub_command_t cmd __attribute__ ((unused)), | ||||
| 	       int argc, char **args) | ||||
| { | ||||
|   int argn = 0; | ||||
| 
 | ||||
|   if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) | ||||
|     argc--; | ||||
| 
 | ||||
|   return test_parse (args, &argn, argc) ? GRUB_ERR_NONE | ||||
|     : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); | ||||
| } | ||||
| 
 | ||||
| static grub_command_t cmd_1, cmd_2; | ||||
|  | ||||
| GRUB_MOD_INIT(test) | ||||
| { | ||||
|   cmd_1 = grub_register_command ("[", grub_cmd_test, | ||||
| 				 N_("EXPRESSION ]"), N_("Evaluate an expression.")); | ||||
|   cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; | ||||
|   cmd_2 = grub_register_command ("test", grub_cmd_test, | ||||
| 				 N_("EXPRESSION"), N_("Evaluate an expression.")); | ||||
|   cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; | ||||
| } | ||||
| 
 | ||||
| GRUB_MOD_FINI(test) | ||||
| { | ||||
|   grub_unregister_command (cmd_1); | ||||
|   grub_unregister_command (cmd_2); | ||||
| } | ||||
| @ -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) | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -27,7 +27,7 @@ | ||||
| #include <grub/i18n.h> | ||||
| #include <grub/ventoy.h> | ||||
| 
 | ||||
| #define	GRUB_CACHE_TIMEOUT	2 | ||||
| #define	GRUB_CACHE_TIMEOUT	10 | ||||
| 
 | ||||
| /* The last time the disk was used.  */ | ||||
| static grub_uint64_t grub_last_time = 0; | ||||
|  | ||||
| @ -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) | ||||
| { | ||||
|  | ||||
| @ -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 (); | ||||
| 
 | ||||
|  | ||||
| @ -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: | ||||
|  | ||||
| @ -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; | ||||
| @ -1420,6 +1447,14 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) | ||||
|     param->vtoy_reserved[0] = g_ventoy_break_level; | ||||
|     param->vtoy_reserved[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 }, | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -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__ */ | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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,15 +312,23 @@ 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); | ||||
|     while (node) | ||||
|     { | ||||
|         next = node->next; | ||||
|         grub_free(node); | ||||
|         node = next; | ||||
|     } | ||||
| 
 | ||||
|     grub_memset(&g_wim_data, 0, sizeof(g_wim_data)); | ||||
|     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)); | ||||
| @ -597,7 +839,7 @@ 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); | ||||
|     for (node = g_wim_patch_head; node; node = node->next) | ||||
|     { | ||||
|         wim_data = &node->wim_data; | ||||
|         if (0 == node->valid) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
|          | ||||
|     /* 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); | ||||
|         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 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); | ||||
|         //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); | ||||
|     for (node = g_wim_patch_head; node; node = node->next) | ||||
|     { | ||||
|         if (0 == node->valid) | ||||
|         { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|     cur->mem_sector_start   = cur->remap_sector_end; | ||||
|     cur->mem_sector_end     = cur->mem_sector_start + mem_secs; | ||||
|     cur->mem_sector_offset  = offset; | ||||
|         wim_data = &node->wim_data; | ||||
| 
 | ||||
|     grub_memcpy(override + offset, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len); | ||||
|     offset += g_wim_data.bin_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; | ||||
| 
 | ||||
|     grub_memcpy(override + offset, g_wim_data.new_meta_data, g_wim_data.new_meta_len); | ||||
|     offset += g_wim_data.new_meta_align_len; | ||||
|         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); | ||||
|          | ||||
|     grub_memcpy(override + offset, g_wim_data.new_lookup_data, g_wim_data.new_lookup_len); | ||||
|     offset += g_wim_data.new_lookup_align_len; | ||||
|         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 */ | ||||
|  | ||||
							
								
								
									
										243
									
								
								GRUB2/MOD_SRC/grub-2.04/include/grub/file.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								GRUB2/MOD_SRC/grub-2.04/include/grub/file.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | ||||
| /*
 | ||||
|  *  GRUB  --  GRand Unified Bootloader | ||||
|  *  Copyright (C) 2002,2007  Free Software Foundation, Inc. | ||||
|  * | ||||
|  *  GRUB is free software: you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License as published by | ||||
|  *  the Free Software Foundation, either version 3 of the License, or | ||||
|  *  (at your option) any later version. | ||||
|  * | ||||
|  *  GRUB is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *  GNU General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU General Public License | ||||
|  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #ifndef GRUB_FILE_HEADER | ||||
| #define GRUB_FILE_HEADER	1 | ||||
| 
 | ||||
| #include <grub/types.h> | ||||
| #include <grub/err.h> | ||||
| #include <grub/device.h> | ||||
| #include <grub/fs.h> | ||||
| #include <grub/disk.h> | ||||
| 
 | ||||
| enum grub_file_type | ||||
|   { | ||||
|     GRUB_FILE_TYPE_NONE = 0, | ||||
|     /* GRUB module to be loaded.  */ | ||||
|     GRUB_FILE_TYPE_GRUB_MODULE, | ||||
|     /* Loopback file to be represented as disk.  */ | ||||
|     GRUB_FILE_TYPE_LOOPBACK, | ||||
|     /* Linux kernel to be loaded.  */ | ||||
|     GRUB_FILE_TYPE_LINUX_KERNEL, | ||||
|     /* Linux initrd.  */ | ||||
|     GRUB_FILE_TYPE_LINUX_INITRD, | ||||
| 
 | ||||
|     /* Multiboot kernel.  */ | ||||
|     GRUB_FILE_TYPE_MULTIBOOT_KERNEL, | ||||
|     /* Multiboot module.  */ | ||||
|     GRUB_FILE_TYPE_MULTIBOOT_MODULE, | ||||
| 
 | ||||
|     /* Xen hypervisor - used on ARM only. */ | ||||
|     GRUB_FILE_TYPE_XEN_HYPERVISOR, | ||||
|     /* Xen module - used on ARM only. */ | ||||
|     GRUB_FILE_TYPE_XEN_MODULE, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_BSD_KERNEL, | ||||
|     GRUB_FILE_TYPE_FREEBSD_ENV, | ||||
|     GRUB_FILE_TYPE_FREEBSD_MODULE, | ||||
|     GRUB_FILE_TYPE_FREEBSD_MODULE_ELF, | ||||
|     GRUB_FILE_TYPE_NETBSD_MODULE, | ||||
|     GRUB_FILE_TYPE_OPENBSD_RAMDISK, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_XNU_INFO_PLIST, | ||||
|     GRUB_FILE_TYPE_XNU_MKEXT, | ||||
|     GRUB_FILE_TYPE_XNU_KEXT, | ||||
|     GRUB_FILE_TYPE_XNU_KERNEL, | ||||
|     GRUB_FILE_TYPE_XNU_RAMDISK, | ||||
|     GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE, | ||||
|     GRUB_FILE_XNU_DEVPROP, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_PLAN9_KERNEL, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_NTLDR, | ||||
|     GRUB_FILE_TYPE_TRUECRYPT, | ||||
|     GRUB_FILE_TYPE_FREEDOS, | ||||
|     GRUB_FILE_TYPE_PXECHAINLOADER, | ||||
|     GRUB_FILE_TYPE_PCCHAINLOADER, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_COREBOOT_CHAINLOADER, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE, | ||||
| 
 | ||||
|     /* File holding signature.  */ | ||||
|     GRUB_FILE_TYPE_SIGNATURE, | ||||
|     /* File holding public key to verify signature once.  */ | ||||
|     GRUB_FILE_TYPE_PUBLIC_KEY, | ||||
|     /* File holding public key to add to trused keys.  */ | ||||
|     GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, | ||||
|     /* File of which we intend to print a blocklist to the user.  */ | ||||
|     GRUB_FILE_TYPE_PRINT_BLOCKLIST, | ||||
|     /* File we intend to use for test loading or testing speed.  */ | ||||
|     GRUB_FILE_TYPE_TESTLOAD, | ||||
|     /* File we open only to get its size. E.g. in ls output.  */ | ||||
|     GRUB_FILE_TYPE_GET_SIZE, | ||||
|     /* Font file.  */ | ||||
|     GRUB_FILE_TYPE_FONT, | ||||
|     /* File holding encryption key for encrypted ZFS.  */ | ||||
|     GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY, | ||||
|     /* File we open n grub-fstest.  */ | ||||
|     GRUB_FILE_TYPE_FSTEST, | ||||
|     /* File we open n grub-mount.  */ | ||||
|     GRUB_FILE_TYPE_MOUNT, | ||||
|     /* File which we attempt to identify the type of.  */ | ||||
|     GRUB_FILE_TYPE_FILE_ID, | ||||
|     /* File holding ACPI table.  */ | ||||
|     GRUB_FILE_TYPE_ACPI_TABLE, | ||||
|     /* File holding Device Tree.  */ | ||||
|     GRUB_FILE_TYPE_DEVICE_TREE_IMAGE, | ||||
|     /* File we intend show to user.  */ | ||||
|     GRUB_FILE_TYPE_CAT, | ||||
|     GRUB_FILE_TYPE_HEXCAT, | ||||
|     /* One of pair of files we intend to compare.  */ | ||||
|     GRUB_FILE_TYPE_CMP, | ||||
|     /* List of hashes for hashsum.  */ | ||||
|     GRUB_FILE_TYPE_HASHLIST, | ||||
|     /* File hashed by hashsum.  */ | ||||
|     GRUB_FILE_TYPE_TO_HASH, | ||||
|     /* Keyboard layout.  */ | ||||
|     GRUB_FILE_TYPE_KEYBOARD_LAYOUT, | ||||
|     /* Picture file.  */ | ||||
|     GRUB_FILE_TYPE_PIXMAP, | ||||
|     /* *.lst shipped by GRUB.  */ | ||||
|     GRUB_FILE_TYPE_GRUB_MODULE_LIST, | ||||
|     /* config file.  */ | ||||
|     GRUB_FILE_TYPE_CONFIG, | ||||
|     GRUB_FILE_TYPE_THEME, | ||||
|     GRUB_FILE_TYPE_GETTEXT_CATALOG, | ||||
|     GRUB_FILE_TYPE_FS_SEARCH, | ||||
|     GRUB_FILE_TYPE_AUDIO, | ||||
|     GRUB_FILE_TYPE_VBE_DUMP, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_LOADENV, | ||||
|     GRUB_FILE_TYPE_SAVEENV, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_VERIFY_SIGNATURE, | ||||
| 
 | ||||
|     GRUB_FILE_TYPE_MASK = 0xffff, | ||||
| 
 | ||||
|     /* --skip-sig is specified.  */ | ||||
|     GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000, | ||||
|     GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000 | ||||
|   }; | ||||
| 
 | ||||
| /* File description.  */ | ||||
| struct grub_file | ||||
| { | ||||
|   /* File name.  */ | ||||
|   char *name; | ||||
| 
 | ||||
|   /* The underlying device.  */ | ||||
|   grub_device_t device; | ||||
| 
 | ||||
|   /* The underlying filesystem.  */ | ||||
|   grub_fs_t fs; | ||||
| 
 | ||||
|   /* The current offset.  */ | ||||
|   grub_off_t offset; | ||||
|   grub_off_t progress_offset; | ||||
| 
 | ||||
|   /* Progress info. */ | ||||
|   grub_uint64_t last_progress_time; | ||||
|   grub_off_t last_progress_offset; | ||||
|   grub_uint64_t estimated_speed; | ||||
| 
 | ||||
|   /* The file size.  */ | ||||
|   grub_off_t size; | ||||
| 
 | ||||
|   /* If file is not easily seekable. Should be set by underlying layer.  */ | ||||
|   int not_easily_seekable; | ||||
| 
 | ||||
|   /* Filesystem-specific data.  */ | ||||
|   void *data; | ||||
| 
 | ||||
|   /* This is called when a sector is read. Used only for a disk device.  */ | ||||
|   grub_disk_read_hook_t read_hook; | ||||
| 
 | ||||
|   /* Caller-specific data passed to the read hook.  */ | ||||
|   void *read_hook_data; | ||||
| }; | ||||
| typedef struct grub_file *grub_file_t; | ||||
| 
 | ||||
| extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); | ||||
| 
 | ||||
| /* Filters with lower ID are executed first.  */ | ||||
| typedef enum grub_file_filter_id | ||||
|   { | ||||
|     GRUB_FILE_FILTER_VERIFY, | ||||
|     GRUB_FILE_FILTER_GZIO, | ||||
|     GRUB_FILE_FILTER_XZIO, | ||||
|     GRUB_FILE_FILTER_LZOPIO, | ||||
|     GRUB_FILE_FILTER_MAX, | ||||
|     GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, | ||||
|     GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, | ||||
|   } grub_file_filter_id_t; | ||||
| 
 | ||||
| typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type); | ||||
| 
 | ||||
| extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX]; | ||||
| 
 | ||||
| static inline void | ||||
| grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter) | ||||
| { | ||||
|   grub_file_filters[id] = filter; | ||||
| } | ||||
| 
 | ||||
| static inline void | ||||
| grub_file_filter_unregister (grub_file_filter_id_t id) | ||||
| { | ||||
|   grub_file_filters[id] = 0; | ||||
| } | ||||
| 
 | ||||
| /* Get a device name from NAME.  */ | ||||
| char *EXPORT_FUNC(grub_file_get_device_name) (const char *name); | ||||
| 
 | ||||
| int EXPORT_FUNC(ventoy_check_file_exist) (const char * fmt, ...); | ||||
| grub_file_t EXPORT_FUNC(grub_file_open) (const char *name, enum grub_file_type type); | ||||
| grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf, | ||||
| 					  grub_size_t len); | ||||
| grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset); | ||||
| grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file); | ||||
| 
 | ||||
| /* Return value of grub_file_size() in case file size is unknown. */ | ||||
| #define GRUB_FILE_SIZE_UNKNOWN	 0xffffffffffffffffULL | ||||
| 
 | ||||
| static inline grub_off_t | ||||
| grub_file_size (const grub_file_t file) | ||||
| { | ||||
|   return file->size; | ||||
| } | ||||
| 
 | ||||
| static inline grub_off_t | ||||
| grub_file_tell (const grub_file_t file) | ||||
| { | ||||
|   return file->offset; | ||||
| } | ||||
| 
 | ||||
| static inline int | ||||
| grub_file_seekable (const grub_file_t file) | ||||
| { | ||||
|   return !file->not_easily_seekable; | ||||
| } | ||||
| 
 | ||||
| grub_file_t | ||||
| grub_file_offset_open (grub_file_t parent, enum grub_file_type type, | ||||
| 		       grub_off_t start, grub_off_t size); | ||||
| void | ||||
| grub_file_offset_close (grub_file_t file); | ||||
| 
 | ||||
| #endif /* ! GRUB_FILE_HEADER */ | ||||
| @ -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); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
							
								
								
									
										70
									
								
								IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								IMG/cpio/ventoy/hook/kiosk/ventoy-disk.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| #!/ventoy/busybox/sh | ||||
| #************************************************************************************ | ||||
| # Copyright (c) 2020, longpanda <admin@ventoy.net> | ||||
| #  | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License as | ||||
| # published by the Free Software Foundation; either version 3 of the | ||||
| # License, or (at your option) any later version. | ||||
| #  | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| # General Public License for more details. | ||||
| #  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
| #  | ||||
| #************************************************************************************ | ||||
| 
 | ||||
| . /ventoy/hook/ventoy-hook-lib.sh | ||||
| 
 | ||||
| VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH | ||||
| 
 | ||||
| ventoy_os_install_dmsetup_by_unsquashfs() { | ||||
|     vtlog "ventoy_os_install_dmsetup_by_unsquashfs $*" | ||||
|      | ||||
|     vtKerVer=$(uname -r) | ||||
|     vtKoPo=$(ventoy_get_module_postfix) | ||||
|     vtlog "vtKerVer=$vtKerVer vtKoPo=$vtKoPo" | ||||
| 
 | ||||
|     vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/iso_file_list | ||||
| 
 | ||||
|     vtline=$(grep '[-][-] .*kernel.xzm '  $VTOY_PATH/iso_file_list)     | ||||
|     sector=$(echo $vtline | awk '{print $(NF-1)}') | ||||
|     length=$(echo $vtline | awk '{print $NF}') | ||||
|      | ||||
|     vtlog "vtline=$vtline  sector=$sector  length=$length" | ||||
|      | ||||
|     vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $1 -s $sector -l $length -o $VTOY_PATH/kernel.xzm | ||||
|     mkdir -p $VTOY_PATH/sqfs   | ||||
|     mount $VTOY_PATH/kernel.xzm  $VTOY_PATH/sqfs | ||||
| 
 | ||||
|     dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo"     | ||||
|      | ||||
|     if [ -e $VTOY_PATH/sqfs${dmModPath} ]; then | ||||
|         vtlog "success $VTOY_PATH/sqfs${dmModPath}" | ||||
|         insmod $VTOY_PATH/sqfs${dmModPath} | ||||
|     else | ||||
|         vterr "failed $VTOY_PATH/sqfs${dmModPath}" | ||||
|         false | ||||
|     fi | ||||
|      | ||||
|     umount $VTOY_PATH/sqfs | ||||
|     rm -f $VTOY_PATH/kernel.xzm | ||||
| } | ||||
| 
 | ||||
| wait_for_usb_disk_ready | ||||
| 
 | ||||
| vtdiskname=$(get_ventoy_disk_name) | ||||
| if [ "$vtdiskname" = "unknown" ]; then | ||||
|     vtlog "ventoy disk not found" | ||||
|     PATH=$VTPATH_OLD | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
| ventoy_os_install_dmsetup_by_unsquashfs $vtdiskname | ||||
| 
 | ||||
| ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" | ||||
| 
 | ||||
| PATH=$VTPATH_OLD | ||||
							
								
								
									
										22
									
								
								IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								IMG/cpio/ventoy/hook/kiosk/ventoy-hook.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| #!/ventoy/busybox/sh | ||||
| #************************************************************************************ | ||||
| # Copyright (c) 2020, longpanda <admin@ventoy.net> | ||||
| #  | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License as | ||||
| # published by the Free Software Foundation; either version 3 of the | ||||
| # License, or (at your option) any later version. | ||||
| #  | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| # General Public License for more details. | ||||
| #  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
| #  | ||||
| #************************************************************************************ | ||||
| 
 | ||||
| . $VTOY_PATH/hook/ventoy-os-lib.sh | ||||
| 
 | ||||
| $SED '/^ *search [^(]*$/i\    /ventoy/busybox/sh  /ventoy/hook/kiosk/ventoy-disk.sh'  -i /init | ||||
| @ -1,7 +1,29 @@ | ||||
| #!/ventoy/busybox/sh | ||||
| #************************************************************************************ | ||||
| # Copyright (c) 2020, longpanda <admin@ventoy.net> | ||||
| #  | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License as | ||||
| # published by the Free Software Foundation; either version 3 of the | ||||
| # License, or (at your option) any later version. | ||||
| #  | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| # General Public License for more details. | ||||
| #  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
| #  | ||||
| #************************************************************************************ | ||||
| 
 | ||||
| . $VTOY_PATH/hook/ventoy-os-lib.sh | ||||
| 
 | ||||
| ventoy_systemd_udevd_work_around | ||||
| #ventoy_systemd_udevd_work_around | ||||
| #ventoy_add_udev_rule "$VTOY_PATH/hook/mageia/udev_disk_hook.sh %k noreplace" | ||||
| 
 | ||||
| ventoy_set_inotify_script  mageia/ventoy-inotifyd-hook.sh | ||||
| $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/mageia/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/99-ventoy-inotifyd-start.sh | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ventoy_add_udev_rule "$VTOY_PATH/hook/mageia/udev_disk_hook.sh %k noreplace" | ||||
|  | ||||
							
								
								
									
										69
									
								
								IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| #!/ventoy/busybox/sh | ||||
| #************************************************************************************ | ||||
| # Copyright (c) 2020, longpanda <admin@ventoy.net> | ||||
| #  | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License as | ||||
| # published by the Free Software Foundation; either version 3 of the | ||||
| # License, or (at your option) any later version. | ||||
| #  | ||||
| # This program is distributed in the hope that it will be useful, but | ||||
| # WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| # General Public License for more details. | ||||
| #  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
| #  | ||||
| #************************************************************************************ | ||||
| 
 | ||||
| . /ventoy/hook/ventoy-hook-lib.sh | ||||
| 
 | ||||
| if is_ventoy_hook_finished; then | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
| vtlog "##### INOTIFYD: $2/$3 is created ..." | ||||
| 
 | ||||
| VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH | ||||
| 
 | ||||
| if is_inotify_ventoy_part $3; then | ||||
| 
 | ||||
|     vtlog "find ventoy partition ..." | ||||
|     $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace | ||||
|      | ||||
|     blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/')   | ||||
|     vtDM=$(ventoy_find_dm_id ${blkdev_num})    | ||||
|     vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $AWK '{print $2}' | $SED 's/.*"\(.*\)".*/\1/') | ||||
|      | ||||
|     vtlog "blkdev_num=$blkdev_num  vtDM=$vtDM  label $vtLABEL ..." | ||||
|     | ||||
|     if [ -n "$vtLABEL" ]; then | ||||
|         $BUSYBOX_PATH/mkdir -p /dev/disk/by-label/ | ||||
|         ln -s /dev/$vtDM /dev/disk/by-label/$vtLABEL | ||||
|     fi | ||||
|      | ||||
|     # | ||||
|     # cheatcode for mageia | ||||
|     # | ||||
|     # From mageia/soft/drakx/mdk-stage1 source code, we see that the stage1 binary will search  | ||||
|     # /tmp/syslog file to determin whether there is a DAC960 cdrom in the system. | ||||
|     # So we insert some string to /tmp/syslog file to cheat the stage1 program. | ||||
|     # | ||||
|     $BUSYBOX_PATH/mkdir -p /dev/rd | ||||
|     ventoy_copy_device_mapper "/dev/rd/ventoy" | ||||
|     echo 'ventoy cheatcode /dev/rd/ventoy:  model' >> /tmp/syslog | ||||
| 
 | ||||
|     if [ -e /sbin/mgalive-root ]; then | ||||
|         vtlog "set mgalive-root ..." | ||||
|              | ||||
|         $BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid /sbin/blkid | ||||
|         $BUSYBOX_PATH/mkdir -p /dev/mapper | ||||
|         ln -s /dev/$vtDM  /dev/mapper/ventoy      | ||||
|         /sbin/mgalive-root /dev/dm-0     | ||||
|     fi | ||||
|      | ||||
|     set_ventoy_hook_finish | ||||
| fi | ||||
| 
 | ||||
| PATH=$VTPATH_OLD | ||||
| @ -19,22 +19,13 @@ | ||||
| 
 | ||||
| . /ventoy/hook/ventoy-hook-lib.sh | ||||
| 
 | ||||
| if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then | ||||
|     exit 0 | ||||
| vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) | ||||
| 
 | ||||
| vtdisk=$(get_ventoy_disk_name) | ||||
| if [ "$vtdisk" = "unknown" ]; then | ||||
|     vtlog "... start inotifyd listen $vtHook ..." | ||||
|     $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook  /dev:n  2>&-  &  | ||||
| else | ||||
|     vtlog "... $vtdisk already exist ..." | ||||
|     $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" | ||||
| fi | ||||
| 
 | ||||
| ventoy_udev_disk_common_hook $* | ||||
| 
 | ||||
| # | ||||
| # cheatcode for mageia | ||||
| # | ||||
| # From mageia/soft/drakx/mdk-stage1 source code, we see that the stage1 binary will search  | ||||
| # /tmp/syslog file to determin whether there is a DAC960 cdrom in the system. | ||||
| # So we insert some string to /tmp/syslog file to cheat the stage1 program. | ||||
| # | ||||
| $BUSYBOX_PATH/mkdir -p /dev/rd | ||||
| ventoy_copy_device_mapper "/dev/rd/ventoy" | ||||
| echo 'ventoy cheatcode /dev/rd/ventoy:  model' >> /tmp/syslog | ||||
| 
 | ||||
| # OK finish | ||||
| set_ventoy_hook_finish | ||||
| @ -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" | ||||
| 
 | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -31,6 +31,12 @@ else | ||||
|             VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs" | ||||
|             break | ||||
|         fi | ||||
|          | ||||
|         if echo $vtParam | $GREP -q '^ks=.*:/'; then | ||||
|             vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') | ||||
|             VTKS="ks=hd:/dev/dm-0:$vtRawKs" | ||||
|             break | ||||
|         fi | ||||
|     done | ||||
| fi | ||||
| 
 | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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                                  # | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										57
									
								
								INSTALL/grub/debug.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								INSTALL/grub/debug.cfg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| submenu 'Check plugin json configuration (ventoy.json)' { | ||||
|     menuentry 'Check global control plugin configuration' { | ||||
|         set pager=1 | ||||
|         vt_check_plugin_json $iso_path control $iso_path | ||||
|          | ||||
|         echo -e "\npress ENTER to exit ..." | ||||
|         read vtInputKey | ||||
|         unset pager | ||||
|     } | ||||
|      | ||||
|     menuentry 'Check theme plugin configuration' { | ||||
|         set pager=1 | ||||
|         vt_check_plugin_json $iso_path theme $iso_path | ||||
|          | ||||
|         echo -e "\npress ENTER to exit ..." | ||||
|         read vtInputKey | ||||
|         unset pager | ||||
|     } | ||||
|      | ||||
|     menuentry 'Check auto install plugin configuration' { | ||||
|         set pager=1 | ||||
|         vt_check_plugin_json $iso_path auto_install $iso_path | ||||
|          | ||||
|         echo -e "\npress ENTER to exit ..." | ||||
|         read vtInputKey | ||||
|         unset pager | ||||
|     } | ||||
|      | ||||
|     menuentry 'Check persistence plugin configuration' { | ||||
|         set pager=1 | ||||
|         vt_check_plugin_json $iso_path persistence $iso_path | ||||
|          | ||||
|         echo -e "\n############### dump persistence ###############" | ||||
|         vt_dump_persistence | ||||
|          | ||||
|         echo -e "\npress ENTER to exit ..." | ||||
|         read vtInputKey | ||||
|         unset pager | ||||
|     } | ||||
|      | ||||
|     menuentry 'Check menu alias plugin configuration' { | ||||
|         set pager=1 | ||||
|         vt_check_plugin_json $iso_path menu_alias $iso_path | ||||
|          | ||||
|         echo -e "\npress ENTER to exit ..." | ||||
|         read vtInputKey | ||||
|         unset pager | ||||
|     } | ||||
|      | ||||
|     menuentry 'Return to previous menu [Esc]' VTOY_RET { | ||||
|         echo 'Return ...' | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| menuentry 'Return to previous menu [Esc]' VTOY_RET { | ||||
|     echo 'Return ...' | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								INSTALL/grub/fonts/unicode.pf2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								INSTALL/grub/fonts/unicode.pf2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -16,14 +16,38 @@ | ||||
| #  | ||||
| #************************************************************************************ | ||||
| 
 | ||||
| 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 | ||||
|      | ||||
|     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 | ||||
| @ -34,18 +58,10 @@ function get_os_type { | ||||
|     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 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| @ -54,22 +70,37 @@ function locate_initrd { | ||||
| 
 | ||||
|     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 | ||||
| @ -129,17 +160,28 @@ 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_fs_probe" = "iso9660" ]; then | ||||
|             loopback -d loop | ||||
|             vt_iso9660_nojoliet 1             | ||||
|             loopback loop $1$2 | ||||
|         fi | ||||
|          | ||||
|         for file in "efi/microsoft/boot/bcd"; do | ||||
|             vt_windows_collect_wim_patch bcd (loop)/$file                 | ||||
|         done | ||||
| 
 | ||||
|         vt_windows_count_wim_patch vt_wim_cnt | ||||
|         if [ $vt_wim_cnt -eq 0 ]; then | ||||
|             distro_specify_wim_patch_phase2 | ||||
|         fi | ||||
|          | ||||
|         ventoy_debug_pause         | ||||
|         locate_wim | ||||
|     fi | ||||
| 
 | ||||
|     vt_windows_chain_data ${1}${chosen_path}     | ||||
| 
 | ||||
|     if [ -n "${vtdebug_flag}" ]; then | ||||
|         sleep 5 | ||||
|     fi | ||||
|     ventoy_debug_pause | ||||
|      | ||||
|     if [ -n "$vtoy_chain_mem_addr" ]; then | ||||
|         terminal_output  console        | ||||
| @ -147,12 +189,19 @@ function uefi_windows_menu_func { | ||||
|         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 | ||||
| @ -169,17 +218,11 @@ function uefi_linux_menu_func { | ||||
| 
 | ||||
|         # 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} | ||||
| @ -288,31 +344,49 @@ 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_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 | ||||
|     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 | ||||
| @ -353,17 +427,14 @@ function legacy_linux_menu_func { | ||||
|     fi | ||||
|      | ||||
|     vt_linux_chain_data ${1}${chosen_path}     | ||||
|      | ||||
|     if [ -n "${vtdebug_flag}" ]; then | ||||
|         sleep 5 | ||||
|     fi | ||||
|     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,10 +452,10 @@ function legacy_iso_menu_func { | ||||
|         set ventoy_fs_probe=udf | ||||
|     else | ||||
|         set ventoy_fs_probe=iso9660 | ||||
|         vt_iso9660_nojoliet 0 | ||||
|     fi | ||||
|      | ||||
|     loopback loop ${1}${chosen_path} | ||||
|      | ||||
|     get_os_type (loop) | ||||
| 
 | ||||
|     if [ -n "$vtcompat" ]; then | ||||
| @ -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} | ||||
| @ -447,9 +512,8 @@ 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 | ||||
|      | ||||
|     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" | ||||
| @ -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 | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										57
									
								
								INSTALL/grub/localboot.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								INSTALL/grub/localboot.cfg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| 
 | ||||
| if [ "$grub_platform" = "pc" ]; then | ||||
|     menuentry 'Search and boot Windows' {     | ||||
|         if search -n -s -f /bootmgr; then | ||||
|             ntldr /bootmgr | ||||
|         elif search -n -s -f /ntldr; then | ||||
|             ntldr /ntldr | ||||
|         else | ||||
|             echo "Windows NOT found ..." | ||||
|         fi         | ||||
|     } | ||||
|      | ||||
|     menuentry 'Boot the 1st local disk' { | ||||
|         set root=(hd0,1) | ||||
|         chainloader +1 | ||||
|         boot | ||||
|     } | ||||
|      | ||||
|     menuentry 'Boot the 2nd local disk' { | ||||
|         set root=(hd1,1) | ||||
|         chainloader +1 | ||||
|         boot | ||||
|     } | ||||
|      | ||||
|     menuentry 'Boot the 3rd local disk' { | ||||
|         set root=(hd2,1) | ||||
|         chainloader +1 | ||||
|         boot | ||||
|     } | ||||
|      | ||||
| else | ||||
| 
 | ||||
|     menuentry 'Search and boot Windows' {     | ||||
|         if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then | ||||
|             terminal_output  console | ||||
|             chainloader /EFI/Microsoft/Boot/bootmgfw.efi | ||||
|             boot | ||||
|         else | ||||
|             echo "Windows NOT found ..." | ||||
|         fi         | ||||
|     } | ||||
|      | ||||
|     menuentry 'Search and boot BOOTX64.EFI' {     | ||||
|         if search -n -s -f /efi/boot/bootx64.efi; then | ||||
|             terminal_output  console | ||||
|             chainloader /efi/boot/bootx64.efi | ||||
|             boot | ||||
|         else | ||||
|             echo "BOOTX64.EFI NOT found ..." | ||||
|         fi         | ||||
|     } | ||||
| 
 | ||||
| fi | ||||
| 
 | ||||
| menuentry 'Return to menu [Esc]' VTOY_RET { | ||||
|     echo 'Return ...' | ||||
| } | ||||
| @ -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 { | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB | 
| @ -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"}  | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -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 | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -492,9 +492,9 @@ 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); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user