X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/a5c706511b84eb0f9e5f042f18f2f3c9602977c4..1c5aeb35dc927d7127d3db535512c89c9d23372e:/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c index 624055d..f9323cb 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -36,8 +36,10 @@ #include #include +UINT8 *g_iso_data_buf = NULL; UINTN g_iso_buf_size = 0; BOOLEAN gMemdiskMode = FALSE; +BOOLEAN gSector512Mode = FALSE; ventoy_sector_flag *g_sector_flag = NULL; UINT32 g_sector_flag_num = 0; @@ -57,6 +59,63 @@ 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 UINTN g_keyboard_hook_count = 0; +STATIC BOOLEAN g_blockio_start_record_bcd = FALSE; +STATIC BOOLEAN g_blockio_bcd_read_done = FALSE; + +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex = NULL; +STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex = NULL; +STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL; + +STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL; + +STATIC UINT8 g_sector_buf[2048]; +STATIC EFI_BLOCK_READ g_sector_2048_read = NULL; +STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL; + +BOOLEAN ventoy_is_cdrom_dp_exist(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + while (!IsDevicePathEnd(DevicePath)) + { + if (MEDIA_DEVICE_PATH == DevicePath->Type && MEDIA_CDROM_DP == DevicePath->SubType) + { + FreePool(Handles); + return TRUE; + } + + DevicePath = NextDevicePathNode(DevicePath); + } + } + + FreePool(Handles); + return FALSE; +} + +#if 0 +/* Block IO procotol */ +#endif + EFI_STATUS EFIAPI ventoy_block_io_reset ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -89,7 +148,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector ventoy_override_chunk *pOverride = g_override_chunk; EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; - debug("read iso sector %lu count %u", Sector, Count); + debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign); ReadStart = Sector * 2048; ReadEnd = (Sector + Count) * 2048; @@ -102,9 +161,17 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector { MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; } - else + else if (g_chain->disk_sector_size == 1024) { - MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector; + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; } secLeft = pchunk->img_end_sector + 1 - Sector; @@ -114,7 +181,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector MapLba, secRead * 2048, pCurBuf); if (EFI_ERROR(Status)) { - debug("Raw disk read block failed %r", Status); + debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status, MapLba, secRead, pCurBuf); return Status; } @@ -176,9 +243,107 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector } } + if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done) + { + if (*(UINT32 *)Buffer == 0x66676572) + { + g_blockio_bcd_read_done = TRUE; + } + } + return EFI_SUCCESS; } +STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector +( + IN UINT64 Sector, + IN UINTN Count, + IN 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; + UINT8 *pCurBuf = (UINT8 *)Buffer; + ventoy_img_chunk *pchunk = g_chunk; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; + + debug("write 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 if (g_chain->disk_sector_size == 1024) + { + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; + } + + + secLeft = pchunk->img_end_sector + 1 - Sector; + secRead = (Count < secLeft) ? Count : secLeft; + + Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, + MapLba, secRead * 2048, pCurBuf); + if (EFI_ERROR(Status)) + { + debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead); + return Status; + } + + Count -= secRead; + Sector += secRead; + pCurBuf += secRead * 2048; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_ramdisk_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; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize); + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -193,7 +358,15 @@ EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read (VOID)This; (VOID)MediaId; - CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize); + CopyMem(Buffer, g_iso_data_buf + (Lba * 2048), BufferSize); + + if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done) + { + if (*(UINT32 *)Buffer == 0x66676572) + { + g_blockio_bcd_read_done = TRUE; + } + } return EFI_SUCCESS; } @@ -251,7 +424,7 @@ end: return Lba; } -EFI_STATUS EFIAPI ventoy_block_io_read +EFI_STATUS EFIAPI ventoy_block_io_read_real ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, @@ -264,6 +437,8 @@ EFI_STATUS EFIAPI ventoy_block_io_read UINT32 j = 0; UINT32 lbacount = 0; UINT32 secNum = 0; + UINT32 TmpNum = 0; + UINT64 VirtSec = 0; UINT64 offset = 0; EFI_LBA curlba = 0; EFI_LBA lastlba = 0; @@ -271,7 +446,7 @@ EFI_STATUS EFIAPI ventoy_block_io_read ventoy_sector_flag *cur_flag; ventoy_virt_chunk *node; - //debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048); + debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); secNum = BufferSize / 2048; @@ -287,6 +462,26 @@ EFI_STATUS EFIAPI ventoy_block_io_read { return ventoy_read_iso_sector(Lba, secNum, Buffer); } + else if (offset < g_chain->real_img_size_in_bytes) + { + TmpNum = (g_chain->real_img_size_in_bytes - offset) / 2048; + ventoy_read_iso_sector(Lba, TmpNum, Buffer); + + Lba += TmpNum; + secNum -= TmpNum; + Buffer = (UINT8 *)Buffer + (g_chain->real_img_size_in_bytes - offset); + offset = Lba * 2048; + } + + VirtSec = g_chain->virt_img_size_in_bytes / 2048; + if (Lba >= VirtSec) + { + return EFI_SUCCESS; + } + else if (Lba + secNum > VirtSec) + { + secNum = VirtSec - Lba; + } if (secNum > g_sector_flag_num) { @@ -355,6 +550,42 @@ EFI_STATUS EFIAPI ventoy_block_io_read 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 IoAlign = 0; + VOID *NewBuf = NULL; + EFI_STATUS Status = EFI_OUT_OF_RESOURCES; + + if (gBlockData.pRawBlockIo && gBlockData.pRawBlockIo->Media) + { + IoAlign = gBlockData.pRawBlockIo->Media->IoAlign; + } + + if ((IoAlign == 0) || (((UINTN) Buffer & (IoAlign - 1)) == 0)) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, Buffer); + } + else + { + NewBuf = AllocatePages(EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + if (NewBuf) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, NewBuf); + CopyMem(Buffer, NewBuf, BufferSize); + FreePages(NewBuf, EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + } + } + + return Status; +} + EFI_STATUS EFIAPI ventoy_block_io_write ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -364,12 +595,21 @@ EFI_STATUS EFIAPI ventoy_block_io_write IN VOID *Buffer ) { + UINT32 secNum = 0; + UINT64 offset = 0; + (VOID)This; (VOID)MediaId; - (VOID)Lba; - (VOID)BufferSize; - (VOID)Buffer; - return EFI_WRITE_PROTECTED; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + secNum = BufferSize / 2048; + offset = Lba * 2048; + + return ventoy_write_iso_sector(Lba, secNum, Buffer); } EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) @@ -447,7 +687,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -489,7 +729,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -501,15 +741,147 @@ end: return Status; } +EFI_STATUS EFIAPI ventoy_block_io_read_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(CurBuf, g_sector_buf + Mod * 512, BufferSize); + return EFI_SUCCESS; + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(CurBuf, g_sector_buf + Mod * 512, ReadSize); + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_read(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + CopyMem(CurBuf, g_sector_buf, BufferSize); + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_block_io_write_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize); + return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CopyMem(g_sector_buf, CurBuf, BufferSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + + 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(); + + debug("install block io protocol %p", ImageHandle); + ventoy_debug_pause(); + + if (gSector512Mode) + { + gBlockData.Media.BlockSize = 512; + gBlockData.Media.LastBlock = ImgSize / 512 - 1; + } + else + { + gBlockData.Media.BlockSize = 2048; + gBlockData.Media.LastBlock = ImgSize / 2048 - 1; + } - gBlockData.Media.BlockSize = 2048; - gBlockData.Media.LastBlock = ImgSize / 2048 - 1; gBlockData.Media.ReadOnly = TRUE; gBlockData.Media.MediaPresent = 1; gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; @@ -517,8 +889,20 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im 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; + + if (gSector512Mode) + { + g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; + g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write; + pBlockIo->ReadBlocks = ventoy_block_io_read_512; + pBlockIo->WriteBlocks = ventoy_block_io_write_512; + } + else + { + 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, @@ -530,11 +914,10 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im { 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)) @@ -548,7 +931,195 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im return EFI_SUCCESS; } -EFI_STATUS EFIAPI ventoy_wrapper_file_open +#if 0 +/* For file replace */ +#endif + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_fs_open(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes) +{ + (VOID)This; + (VOID)New; + (VOID)Name; + (VOID)Mode; + (VOID)Attributes; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_fs_open(This, New, Name, Mode, Attributes); +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_delete(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data) +{ + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + (VOID)This; + (VOID)Len; + (VOID)Data; + + return EFI_WRITE_PROTECTED; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_file_write(This, &(Token->BufferSize), Token->Buffer); +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_close(EFI_FILE_HANDLE This) +{ + (VOID)This; + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) +{ + (VOID)This; + + if (Position <= g_efi_file_replace.FileSizeBytes) + { + g_efi_file_replace.CurPos = Position; + } + else + { + g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes; + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position) +{ + (VOID)This; + + *Position = g_efi_file_replace.CurPos; + + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data) +{ + EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + + debug("ventoy_wrapper_file_get_info ... %u", *Len); + + if (!CompareGuid(Type, &gEfiFileInfoGuid)) + { + return EFI_INVALID_PARAMETER; + } + + if (*Len == 0) + { + *Len = 384; + return EFI_BUFFER_TOO_SMALL; + } + + ZeroMem(Data, sizeof(EFI_FILE_INFO)); + + Info->Size = sizeof(EFI_FILE_INFO); + Info->FileSize = g_efi_file_replace.FileSizeBytes; + Info->PhysicalSize = g_efi_file_replace.FileSizeBytes; + Info->Attribute = EFI_FILE_READ_ONLY; + //Info->FileName = EFI_FILE_READ_ONLY; + + *Len = Info->Size; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) +{ + EFI_LBA Lba; + UINTN ReadLen = *Len; + + (VOID)This; + + debug("ventoy_wrapper_file_read ... %u", *Len); + + if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes) + { + ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos; + } + + Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart; + + ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data); + + *Len = ReadLen; + + g_efi_file_replace.CurPos += ReadLen; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token) +{ + return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer); +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File) +{ + File->Revision = EFI_FILE_PROTOCOL_REVISION2; + File->Open = ventoy_wrapper_fs_open; + File->Close = ventoy_wrapper_file_close; + File->Delete = ventoy_wrapper_file_delete; + File->Read = ventoy_wrapper_file_read; + File->Write = ventoy_wrapper_file_write; + File->GetPosition = ventoy_wrapper_file_get_pos; + File->SetPosition = ventoy_wrapper_file_set_pos; + File->GetInfo = ventoy_wrapper_file_get_info; + File->SetInfo = ventoy_wrapper_file_set_info; + File->Flush = ventoy_wrapper_file_flush; + File->OpenEx = ventoy_wrapper_file_open_ex; + File->ReadEx = ventoy_wrapper_file_read_ex; + File->WriteEx = ventoy_wrapper_file_write_ex; + File->FlushEx = ventoy_wrapper_file_flush_ex; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open ( EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, @@ -564,6 +1135,8 @@ EFI_STATUS EFIAPI ventoy_wrapper_file_open CHAR8 TmpName[256]; ventoy_virt_chunk *virt = NULL; + debug("## ventoy_wrapper_file_open <%s> ", Name); + Status = g_original_fopen(This, New, Name, Mode, Attributes); if (EFI_ERROR(Status)) { @@ -599,6 +1172,11 @@ EFI_STATUS EFIAPI ventoy_wrapper_file_open return Status; } } + + if (StrCmp(Name, L"\\EFI\\BOOT") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } } return Status; @@ -629,3 +1207,134 @@ EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTO return EFI_SUCCESS; } +#if 0 +/* For auto skip Windows 'Press any key to boot from CD or DVD ...' */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_read_key_ex +( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData +) +{ + /* only hook once before BCD file read */ + if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE) + { + g_keyboard_hook_count++; + + KeyData->Key.ScanCode = SCAN_DELETE; + KeyData->Key.UnicodeChar = 0; + KeyData->KeyState.KeyShiftState = 0; + KeyData->KeyState.KeyToggleState = 0; + + return EFI_SUCCESS; + } + + return g_org_read_key_ex(This, KeyData); +} + +EFI_STATUS EFIAPI ventoy_wrapper_read_key +( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key +) +{ + /* only hook once before BCD file read */ + if (g_keyboard_hook_count == 0 && g_blockio_bcd_read_done == FALSE) + { + g_keyboard_hook_count++; + + Key->ScanCode = SCAN_DELETE; + Key->UnicodeChar = 0; + return EFI_SUCCESS; + } + + return g_org_read_key(This, Key); +} + +EFI_STATUS ventoy_hook_keyboard_start(VOID) +{ + g_blockio_start_record_bcd = TRUE; + g_blockio_bcd_read_done = FALSE; + g_keyboard_hook_count = 0; + + if (g_con_simple_input_ex) + { + g_org_read_key_ex = g_con_simple_input_ex->ReadKeyStrokeEx; + g_con_simple_input_ex->ReadKeyStrokeEx = ventoy_wrapper_read_key_ex; + } + + g_org_read_key = gST->ConIn->ReadKeyStroke; + gST->ConIn->ReadKeyStroke = ventoy_wrapper_read_key; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_keyboard_stop(VOID) +{ + g_blockio_start_record_bcd = FALSE; + g_blockio_bcd_read_done = FALSE; + g_keyboard_hook_count = 0; + + if (g_con_simple_input_ex) + { + g_con_simple_input_ex->ReadKeyStrokeEx = g_org_read_key_ex; + } + + gST->ConIn->ReadKeyStroke = g_org_read_key; + + return EFI_SUCCESS; +} + +#if 0 +/* Fixup the 1st cdrom influnce for Windows boot */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_locate_handle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + + if (EFI_SUCCESS == Status && Protocol && CompareGuid(&gEfiBlockIoProtocolGuid, Protocol)) + { + for (i = 0; i < (*BufferSize) / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + break; + } + } + } + + return Status; +} + +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID) +{ + g_org_locate_handle = gBS->LocateHandle; + gBS->LocateHandle = ventoy_wrapper_locate_handle; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID) +{ + gBS->LocateHandle = g_org_locate_handle; + g_org_locate_handle = NULL; + + return EFI_SUCCESS; +} +