1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include <Library/DebugLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/UefiLib.h>
25 #include <Library/BaseMemoryLib.h>
26 #include <Library/DevicePathLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/UefiRuntimeServicesTableLib.h>
30 #include <Library/UefiApplicationEntryPoint.h>
31 #include <Protocol/LoadedImage.h>
32 #include <Guid/FileInfo.h>
33 #include <Guid/FileSystemInfo.h>
34 #include <Protocol/BlockIo.h>
35 #include <Protocol/RamDisk.h>
36 #include <Protocol/SimpleFileSystem.h>
37 #include <Protocol/DriverBinding.h>
40 UINT8
*g_iso_data_buf
= NULL
;
41 UINTN g_iso_buf_size
= 0;
42 BOOLEAN gMemdiskMode
= FALSE
;
43 BOOLEAN gSector512Mode
= FALSE
;
45 ventoy_sector_flag
*g_sector_flag
= NULL
;
46 UINT32 g_sector_flag_num
= 0;
48 EFI_FILE_OPEN g_original_fopen
= NULL
;
49 EFI_FILE_CLOSE g_original_fclose
= NULL
;
50 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume
= NULL
;
52 /* EFI block device vendor device path GUID */
53 EFI_GUID gVtoyBlockDevicePathGuid
= VTOY_BLOCK_DEVICE_PATH_GUID
;
55 #define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152
57 BOOLEAN g_fixup_iso9660_secover_enable
= FALSE
;
58 BOOLEAN g_fixup_iso9660_secover_start
= FALSE
;
59 UINT64 g_fixup_iso9660_secover_1st_secs
= 0;
60 UINT64 g_fixup_iso9660_secover_cur_secs
= 0;
61 UINT64 g_fixup_iso9660_secover_tot_secs
= 0;
63 STATIC UINTN g_keyboard_hook_count
= 0;
64 STATIC BOOLEAN g_blockio_start_record_bcd
= FALSE
;
65 STATIC BOOLEAN g_blockio_bcd_read_done
= FALSE
;
67 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*g_con_simple_input_ex
= NULL
;
68 STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex
= NULL
;
69 STATIC EFI_INPUT_READ_KEY g_org_read_key
= NULL
;
71 STATIC EFI_LOCATE_HANDLE g_org_locate_handle
= NULL
;
73 STATIC UINT8 g_sector_buf
[2048];
74 STATIC EFI_BLOCK_READ g_sector_2048_read
= NULL
;
75 STATIC EFI_BLOCK_WRITE g_sector_2048_write
= NULL
;
77 STATIC UINTN g_DriverBindWrapperCnt
= 0;
78 STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList
[MAX_DRIVER_BIND_WRAPPER
];
80 BOOLEAN
ventoy_is_cdrom_dp_exist(VOID
)
84 EFI_HANDLE
*Handles
= NULL
;
85 EFI_STATUS Status
= EFI_SUCCESS
;
86 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
= NULL
;
88 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiDevicePathProtocolGuid
,
89 NULL
, &Count
, &Handles
);
90 if (EFI_ERROR(Status
))
95 for (i
= 0; i
< Count
; i
++)
97 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
98 if (EFI_ERROR(Status
))
103 while (!IsDevicePathEnd(DevicePath
))
105 if (MEDIA_DEVICE_PATH
== DevicePath
->Type
&& MEDIA_CDROM_DP
== DevicePath
->SubType
)
111 DevicePath
= NextDevicePathNode(DevicePath
);
120 /* Block IO procotol */
123 EFI_STATUS EFIAPI ventoy_block_io_reset
125 IN EFI_BLOCK_IO_PROTOCOL
*This
,
126 IN BOOLEAN ExtendedVerification
130 (VOID
)ExtendedVerification
;
134 STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector
141 EFI_STATUS Status
= EFI_SUCCESS
;
146 UINT64 ReadStart
= 0;
148 UINT64 OverrideStart
= 0;
149 UINT64 OverrideEnd
= 0;
150 UINT8
*pCurBuf
= (UINT8
*)Buffer
;
151 ventoy_img_chunk
*pchunk
= g_chunk
;
152 ventoy_override_chunk
*pOverride
= g_override_chunk
;
153 EFI_BLOCK_IO_PROTOCOL
*pRawBlockIo
= gBlockData
.pRawBlockIo
;
155 debug("read iso sector %lu count %u Buffer:%p Align:%u blk:%u",
156 Sector
, Count
, Buffer
, pRawBlockIo
->Media
->IoAlign
, pRawBlockIo
->Media
->BlockSize
);
158 ReadStart
= Sector
* 2048;
159 ReadEnd
= (Sector
+ Count
) * 2048;
161 for (i
= 0; Count
> 0 && i
< g_img_chunk_num
; i
++, pchunk
++)
163 if (Sector
>= pchunk
->img_start_sector
&& Sector
<= pchunk
->img_end_sector
)
165 if (g_chain
->disk_sector_size
== 512)
167 MapLba
= (Sector
- pchunk
->img_start_sector
) * 4 + pchunk
->disk_start_sector
;
169 else if (g_chain
->disk_sector_size
== 1024)
171 MapLba
= (Sector
- pchunk
->img_start_sector
) * 2 + pchunk
->disk_start_sector
;
173 else if (g_chain
->disk_sector_size
== 2048)
175 MapLba
= (Sector
- pchunk
->img_start_sector
) + pchunk
->disk_start_sector
;
177 else if (g_chain
->disk_sector_size
== 4096)
179 MapLba
= ((Sector
- pchunk
->img_start_sector
) >> 1) + pchunk
->disk_start_sector
;
182 secLeft
= pchunk
->img_end_sector
+ 1 - Sector
;
183 secRead
= (Count
< secLeft
) ? Count
: secLeft
;
185 Status
= pRawBlockIo
->ReadBlocks(pRawBlockIo
, pRawBlockIo
->Media
->MediaId
,
186 MapLba
, secRead
* 2048, pCurBuf
);
187 if (EFI_ERROR(Status
))
189 debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status
, MapLba
, secRead
, pCurBuf
);
195 pCurBuf
+= secRead
* 2048;
199 if (ReadStart
> g_chain
->real_img_size_in_bytes
)
205 pCurBuf
= (UINT8
*)Buffer
;
206 for (i
= 0; i
< g_override_chunk_num
; i
++, pOverride
++)
208 OverrideStart
= pOverride
->img_offset
;
209 OverrideEnd
= pOverride
->img_offset
+ pOverride
->override_size
;
211 if (OverrideStart
>= ReadEnd
|| ReadStart
>= OverrideEnd
)
216 if (ReadStart
<= OverrideStart
)
218 if (ReadEnd
<= OverrideEnd
)
220 CopyMem(pCurBuf
+ OverrideStart
- ReadStart
, pOverride
->override_data
, ReadEnd
- OverrideStart
);
224 CopyMem(pCurBuf
+ OverrideStart
- ReadStart
, pOverride
->override_data
, pOverride
->override_size
);
229 if (ReadEnd
<= OverrideEnd
)
231 CopyMem(pCurBuf
, pOverride
->override_data
+ ReadStart
- OverrideStart
, ReadEnd
- ReadStart
);
235 CopyMem(pCurBuf
, pOverride
->override_data
+ ReadStart
- OverrideStart
, OverrideEnd
- ReadStart
);
239 if (g_fixup_iso9660_secover_enable
&& (!g_fixup_iso9660_secover_start
) &&
240 pOverride
->override_size
== sizeof(ventoy_iso9660_override
))
242 ventoy_iso9660_override
*dirent
= (ventoy_iso9660_override
*)pOverride
->override_data
;
243 if (dirent
->first_sector
>= VENTOY_ISO9660_SECTOR_OVERFLOW
)
245 g_fixup_iso9660_secover_start
= TRUE
;
246 g_fixup_iso9660_secover_cur_secs
= 0;
251 if (g_blockio_start_record_bcd
&& FALSE
== g_blockio_bcd_read_done
)
253 if (*(UINT32
*)Buffer
== 0x66676572)
255 g_blockio_bcd_read_done
= TRUE
;
262 STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector
269 EFI_STATUS Status
= EFI_SUCCESS
;
274 UINT64 ReadStart
= 0;
276 UINT8
*pCurBuf
= (UINT8
*)Buffer
;
277 ventoy_img_chunk
*pchunk
= g_chunk
;
278 EFI_BLOCK_IO_PROTOCOL
*pRawBlockIo
= gBlockData
.pRawBlockIo
;
280 debug("write iso sector %lu count %u", Sector
, Count
);
282 ReadStart
= Sector
* 2048;
283 ReadEnd
= (Sector
+ Count
) * 2048;
285 for (i
= 0; Count
> 0 && i
< g_img_chunk_num
; i
++, pchunk
++)
287 if (Sector
>= pchunk
->img_start_sector
&& Sector
<= pchunk
->img_end_sector
)
289 if (g_chain
->disk_sector_size
== 512)
291 MapLba
= (Sector
- pchunk
->img_start_sector
) * 4 + pchunk
->disk_start_sector
;
293 else if (g_chain
->disk_sector_size
== 1024)
295 MapLba
= (Sector
- pchunk
->img_start_sector
) * 2 + pchunk
->disk_start_sector
;
297 else if (g_chain
->disk_sector_size
== 2048)
299 MapLba
= (Sector
- pchunk
->img_start_sector
) + pchunk
->disk_start_sector
;
301 else if (g_chain
->disk_sector_size
== 4096)
303 MapLba
= ((Sector
- pchunk
->img_start_sector
) >> 1) + pchunk
->disk_start_sector
;
307 secLeft
= pchunk
->img_end_sector
+ 1 - Sector
;
308 secRead
= (Count
< secLeft
) ? Count
: secLeft
;
310 Status
= pRawBlockIo
->WriteBlocks(pRawBlockIo
, pRawBlockIo
->Media
->MediaId
,
311 MapLba
, secRead
* 2048, pCurBuf
);
312 if (EFI_ERROR(Status
))
314 debug("Raw disk write block failed %r LBA:%lu Count:%u", Status
, MapLba
, secRead
);
320 pCurBuf
+= secRead
* 2048;
327 EFI_STATUS EFIAPI ventoy_block_io_ramdisk_write
329 IN EFI_BLOCK_IO_PROTOCOL
*This
,
344 return EFI_WRITE_PROTECTED
;
347 CopyMem(g_iso_data_buf
+ (Lba
* 2048), Buffer
, BufferSize
);
352 EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read
354 IN EFI_BLOCK_IO_PROTOCOL
*This
,
361 //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048);
366 CopyMem(Buffer
, g_iso_data_buf
+ (Lba
* 2048), BufferSize
);
368 if (g_blockio_start_record_bcd
&& FALSE
== g_blockio_bcd_read_done
)
370 if (*(UINT32
*)Buffer
== 0x66676572)
372 g_blockio_bcd_read_done
= TRUE
;
379 EFI_LBA EFIAPI
ventoy_fixup_iso9660_sector(IN EFI_LBA Lba
, UINT32 secNum
)
383 if (g_fixup_iso9660_secover_cur_secs
> 0)
385 Lba
+= VENTOY_ISO9660_SECTOR_OVERFLOW
;
386 g_fixup_iso9660_secover_cur_secs
+= secNum
;
387 if (g_fixup_iso9660_secover_cur_secs
>= g_fixup_iso9660_secover_tot_secs
)
389 g_fixup_iso9660_secover_start
= FALSE
;
395 ventoy_iso9660_override
*dirent
;
396 ventoy_override_chunk
*pOverride
;
398 for (i
= 0, pOverride
= g_override_chunk
; i
< g_override_chunk_num
; i
++, pOverride
++)
400 dirent
= (ventoy_iso9660_override
*)pOverride
->override_data
;
401 if (Lba
== dirent
->first_sector
)
403 g_fixup_iso9660_secover_start
= FALSE
;
408 if (g_fixup_iso9660_secover_start
)
410 for (i
= 0, pOverride
= g_override_chunk
; i
< g_override_chunk_num
; i
++, pOverride
++)
412 dirent
= (ventoy_iso9660_override
*)pOverride
->override_data
;
413 if (Lba
+ VENTOY_ISO9660_SECTOR_OVERFLOW
== dirent
->first_sector
)
415 g_fixup_iso9660_secover_tot_secs
= (dirent
->size
+ 2047) / 2048;
416 g_fixup_iso9660_secover_cur_secs
= secNum
;
417 if (g_fixup_iso9660_secover_cur_secs
>= g_fixup_iso9660_secover_tot_secs
)
419 g_fixup_iso9660_secover_start
= FALSE
;
421 Lba
+= VENTOY_ISO9660_SECTOR_OVERFLOW
;
432 EFI_STATUS EFIAPI ventoy_block_io_read_real
434 IN EFI_BLOCK_IO_PROTOCOL
*This
,
451 ventoy_sector_flag
*cur_flag
;
452 ventoy_virt_chunk
*node
;
454 debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32
)Lba
, (UINT32
)BufferSize
/ 2048, Buffer
);
456 secNum
= BufferSize
/ 2048;
458 /* Workaround for SSTR PE loader error */
459 if (g_fixup_iso9660_secover_start
)
461 Lba
= ventoy_fixup_iso9660_sector(Lba
, secNum
);
466 if (offset
+ BufferSize
<= g_chain
->real_img_size_in_bytes
)
468 return ventoy_read_iso_sector(Lba
, secNum
, Buffer
);
470 else if (offset
< g_chain
->real_img_size_in_bytes
)
472 TmpNum
= (g_chain
->real_img_size_in_bytes
- offset
) / 2048;
473 ventoy_read_iso_sector(Lba
, TmpNum
, Buffer
);
477 Buffer
= (UINT8
*)Buffer
+ (g_chain
->real_img_size_in_bytes
- offset
);
481 VirtSec
= g_chain
->virt_img_size_in_bytes
/ 2048;
486 else if (Lba
+ secNum
> VirtSec
)
488 secNum
= VirtSec
- Lba
;
491 debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32
)Lba
, (UINT32
)BufferSize
/ 2048, Buffer
);
493 if (secNum
> g_sector_flag_num
)
495 cur_flag
= AllocatePool(secNum
* sizeof(ventoy_sector_flag
));
496 if (NULL
== cur_flag
)
498 return EFI_OUT_OF_RESOURCES
;
501 FreePool(g_sector_flag
);
502 g_sector_flag
= cur_flag
;
503 g_sector_flag_num
= secNum
;
506 for (curlba
= Lba
, cur_flag
= g_sector_flag
, j
= 0; j
< secNum
; j
++, curlba
++, cur_flag
++)
509 for (node
= g_virt_chunk
, i
= 0; i
< g_virt_chunk_num
; i
++, node
++)
511 if (curlba
>= node
->mem_sector_start
&& curlba
< node
->mem_sector_end
)
513 CopyMem((UINT8
*)Buffer
+ j
* 2048,
514 (char *)g_virt_chunk
+ node
->mem_sector_offset
+ (curlba
- node
->mem_sector_start
) * 2048,
519 else if (curlba
>= node
->remap_sector_start
&& curlba
< node
->remap_sector_end
)
521 cur_flag
->remap_lba
= node
->org_sector_start
+ curlba
- node
->remap_sector_start
;
528 for (curlba
= Lba
, cur_flag
= g_sector_flag
, j
= 0; j
< secNum
; j
++, curlba
++, cur_flag
++)
530 if (cur_flag
->flag
== 2)
534 lastbuffer
= (UINT8
*)Buffer
+ j
* 2048;
535 lastlba
= cur_flag
->remap_lba
;
538 else if (lastlba
+ lbacount
== cur_flag
->remap_lba
)
544 ventoy_read_iso_sector(lastlba
, lbacount
, lastbuffer
);
545 lastbuffer
= (UINT8
*)Buffer
+ j
* 2048;
546 lastlba
= cur_flag
->remap_lba
;
554 ventoy_read_iso_sector(lastlba
, lbacount
, lastbuffer
);
560 EFI_STATUS EFIAPI ventoy_block_io_read
562 IN EFI_BLOCK_IO_PROTOCOL
*This
,
571 EFI_STATUS Status
= EFI_OUT_OF_RESOURCES
;
573 if (gBlockData
.pRawBlockIo
&& gBlockData
.pRawBlockIo
->Media
)
575 IoAlign
= gBlockData
.pRawBlockIo
->Media
->IoAlign
;
578 if ((IoAlign
== 0) || (((UINTN
) Buffer
& (IoAlign
- 1)) == 0))
580 Status
= ventoy_block_io_read_real(This
, MediaId
, Lba
, BufferSize
, Buffer
);
584 NewBuf
= AllocatePages(EFI_SIZE_TO_PAGES(BufferSize
+ IoAlign
));
587 Status
= ventoy_block_io_read_real(This
, MediaId
, Lba
, BufferSize
, NewBuf
);
588 CopyMem(Buffer
, NewBuf
, BufferSize
);
589 FreePages(NewBuf
, EFI_SIZE_TO_PAGES(BufferSize
+ IoAlign
));
596 EFI_STATUS EFIAPI ventoy_block_io_write
598 IN EFI_BLOCK_IO_PROTOCOL
*This
,
613 return EFI_WRITE_PROTECTED
;
616 secNum
= BufferSize
/ 2048;
619 return ventoy_write_iso_sector(Lba
, secNum
, Buffer
);
622 EFI_STATUS EFIAPI
ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL
*This
)
628 STATIC UINTN
ventoy_get_current_device_path_id(VOID
)
634 BOOLEAN Find
= FALSE
;
635 EFI_HANDLE
*Handles
= NULL
;
636 EFI_STATUS Status
= EFI_SUCCESS
;
637 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
= NULL
;
638 VENDOR_DEVICE_PATH
*venPath
= NULL
;
640 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiDevicePathProtocolGuid
,
641 NULL
, &Count
, &Handles
);
642 if (EFI_ERROR(Status
))
647 for (i
= 0; i
< Count
; i
++)
649 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
650 if (EFI_ERROR(Status
))
655 if (DevicePath
->Type
== HARDWARE_DEVICE_PATH
&& DevicePath
->SubType
== HW_VENDOR_DP
)
657 venPath
= (VENDOR_DEVICE_PATH
*)DevicePath
;
658 if (CompareGuid(&venPath
->Guid
, &gVtoyBlockDevicePathGuid
))
660 CurId
= StrDecimalToUintn((CHAR16
*)(venPath
+ 1) + StrLen(L
"ventoy_"));
661 MaxId
= MAX(MaxId
, CurId
);
669 return Find
? (MaxId
+ 1) : 0;
672 EFI_STATUS EFIAPI
ventoy_fill_device_path(VOID
)
674 UINTN CurVtoyDpId
= 0;
676 UINT8 TmpBuf
[128] = {0};
677 VENDOR_DEVICE_PATH
*venPath
= NULL
;
678 CHAR16 VtoyDpName
[32];
680 CurVtoyDpId
= ventoy_get_current_device_path_id();
681 UnicodeSPrintAsciiFormat(VtoyDpName
, sizeof(VtoyDpName
), "ventoy_%03lu", CurVtoyDpId
);
683 venPath
= (VENDOR_DEVICE_PATH
*)TmpBuf
;
684 NameLen
= StrSize(VtoyDpName
);
685 venPath
->Header
.Type
= HARDWARE_DEVICE_PATH
;
686 venPath
->Header
.SubType
= HW_VENDOR_DP
;
687 venPath
->Header
.Length
[0] = sizeof(VENDOR_DEVICE_PATH
) + NameLen
;
688 venPath
->Header
.Length
[1] = 0;
689 CopyMem(&venPath
->Guid
, &gVtoyBlockDevicePathGuid
, sizeof(EFI_GUID
));
690 CopyMem(venPath
+ 1, VtoyDpName
, NameLen
);
692 gBlockData
.Path
= AppendDevicePathNode(NULL
, (EFI_DEVICE_PATH_PROTOCOL
*)TmpBuf
);
693 gBlockData
.DevicePathCompareLen
= sizeof(VENDOR_DEVICE_PATH
) + NameLen
;
695 debug("gBlockData.Path=<%lu><%s>\n", CurVtoyDpId
, ConvertDevicePathToText(gBlockData
.Path
, FALSE
, FALSE
));
700 EFI_STATUS EFIAPI
ventoy_connect_driver(IN EFI_HANDLE ControllerHandle
, IN CONST CHAR16
*DrvName
)
704 CHAR16
*DriverName
= NULL
;
705 EFI_HANDLE
*Handles
= NULL
;
706 EFI_HANDLE DrvHandles
[2] = { NULL
};
707 EFI_STATUS Status
= EFI_SUCCESS
;
708 EFI_COMPONENT_NAME_PROTOCOL
*NameProtocol
= NULL
;
709 EFI_COMPONENT_NAME2_PROTOCOL
*Name2Protocol
= NULL
;
711 debug("ventoy_connect_driver <%s>...", DrvName
);
713 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiComponentName2ProtocolGuid
,
714 NULL
, &Count
, &Handles
);
715 if (EFI_ERROR(Status
))
720 for (i
= 0; i
< Count
; i
++)
722 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiComponentName2ProtocolGuid
, (VOID
**)&Name2Protocol
);
723 if (EFI_ERROR(Status
))
728 VENTOY_GET_COMPONENT_NAME(Name2Protocol
, DriverName
);
730 if (StrStr(DriverName
, DrvName
))
732 debug("Find driver name2:<%s>: <%s>", DriverName
, DrvName
);
733 DrvHandles
[0] = Handles
[i
];
740 Status
= gBS
->ConnectController(ControllerHandle
, DrvHandles
, NULL
, TRUE
);
741 debug("ventoy_connect_driver:<%s> <%r>", DrvName
, Status
);
745 debug("%s NOT found, now try COMPONENT_NAME", DrvName
);
751 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiComponentNameProtocolGuid
,
752 NULL
, &Count
, &Handles
);
753 if (EFI_ERROR(Status
))
758 for (i
= 0; i
< Count
; i
++)
760 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiComponentNameProtocolGuid
, (VOID
**)&NameProtocol
);
761 if (EFI_ERROR(Status
))
766 VENTOY_GET_COMPONENT_NAME(NameProtocol
, DriverName
);
768 if (StrStr(DriverName
, DrvName
))
770 debug("Find driver name:<%s>: <%s>", DriverName
, DrvName
);
771 DrvHandles
[0] = Handles
[i
];
778 Status
= gBS
->ConnectController(ControllerHandle
, DrvHandles
, NULL
, TRUE
);
779 debug("ventoy_connect_driver:<%s> <%r>", DrvName
, Status
);
783 Status
= EFI_NOT_FOUND
;
792 STATIC BOOLEAN
ventoy_filesystem_need_wrapper(IN CONST CHAR16
*DrvName
)
795 CHAR16 UpperDrvName
[256];
797 StrCpyS(UpperDrvName
, 256, DrvName
);
799 for (i
= 0; i
< 256 && UpperDrvName
[i
]; i
++)
801 if (UpperDrvName
[i
] >= 'a' && UpperDrvName
[i
] <= 'z')
803 UpperDrvName
[i
] = 'A' + (UpperDrvName
[i
] - 'a');
808 * suppress some file system drivers
809 * 1. rEFInd File System Driver
813 if (StrStr(UpperDrvName
, L
"REFIND") && StrStr(UpperDrvName
, L
"FILE SYSTEM"))
821 STATIC VOID ventoy_add_filesystem_wrapper
823 IN EFI_DRIVER_BINDING_PROTOCOL
*DriverBindProtocol
,
824 IN CONST CHAR16
*DriverName
829 if (g_DriverBindWrapperCnt
>= MAX_DRIVER_BIND_WRAPPER
)
831 debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt
);
835 if (!ventoy_filesystem_need_wrapper(DriverName
))
840 for (j
= 0; j
< g_DriverBindWrapperCnt
; j
++)
842 if (g_DriverBindWrapperList
[j
].DriverBinding
== DriverBindProtocol
)
844 debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName
, DriverBindProtocol
, j
, g_DriverBindWrapperCnt
);
849 if (j
>= g_DriverBindWrapperCnt
)
851 g_DriverBindWrapperList
[g_DriverBindWrapperCnt
].DriverBinding
= DriverBindProtocol
;
852 g_DriverBindWrapperList
[g_DriverBindWrapperCnt
].pfOldSupport
= DriverBindProtocol
->Supported
;
853 g_DriverBindWrapperCnt
++;
854 debug("Add driverbinding <%s> %p %lu", DriverName
, DriverBindProtocol
, g_DriverBindWrapperCnt
);
858 STATIC EFI_STATUS
ventoy_find_filesystem_driverbind(VOID
)
862 CHAR16
*DriverName
= NULL
;
863 EFI_HANDLE
*Handles
= NULL
;
864 EFI_STATUS Status
= EFI_SUCCESS
;
865 EFI_COMPONENT_NAME_PROTOCOL
*NameProtocol
= NULL
;
866 EFI_COMPONENT_NAME2_PROTOCOL
*Name2Protocol
= NULL
;
867 EFI_DRIVER_BINDING_PROTOCOL
*DriverBindProtocol
= NULL
;
869 debug("ventoy_find_filesystem_driverbind...");
871 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiComponentName2ProtocolGuid
,
872 NULL
, &Count
, &Handles
);
873 if (EFI_ERROR(Status
))
878 for (i
= 0; i
< Count
; i
++)
880 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiComponentName2ProtocolGuid
, (VOID
**)&Name2Protocol
);
881 if (EFI_ERROR(Status
))
886 VENTOY_GET_COMPONENT_NAME(Name2Protocol
, DriverName
);
888 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiDriverBindingProtocolGuid
, (VOID
**)&DriverBindProtocol
);
889 if (EFI_ERROR(Status
))
891 debug("### 2 No DriverBind <%s> <%r>", DriverName
, Status
);
895 ventoy_add_filesystem_wrapper(DriverBindProtocol
, DriverName
);
902 Status
= gBS
->LocateHandleBuffer(ByProtocol
, &gEfiComponentNameProtocolGuid
,
903 NULL
, &Count
, &Handles
);
904 if (EFI_ERROR(Status
))
909 for (i
= 0; i
< Count
; i
++)
911 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiComponentNameProtocolGuid
, (VOID
**)&NameProtocol
);
912 if (EFI_ERROR(Status
))
917 VENTOY_GET_COMPONENT_NAME(NameProtocol
, DriverName
);
919 Status
= gBS
->HandleProtocol(Handles
[i
], &gEfiDriverBindingProtocolGuid
, (VOID
**)&DriverBindProtocol
);
920 if (EFI_ERROR(Status
))
922 debug("### 1 No DriverBind <%s> <%r>", DriverName
, Status
);
926 ventoy_add_filesystem_wrapper(DriverBindProtocol
, DriverName
);
934 STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support
936 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
937 IN EFI_HANDLE ControllerHandle
,
938 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
942 EFI_STATUS Status
= EFI_SUCCESS
;
943 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
= NULL
;
944 EFI_DRIVER_BINDING_SUPPORTED pfOldSupport
= NULL
;
946 for (i
= 0; i
< g_DriverBindWrapperCnt
; i
++)
948 if (g_DriverBindWrapperList
[i
].DriverBinding
== This
)
950 pfOldSupport
= g_DriverBindWrapperList
[i
].pfOldSupport
;
955 debug("ventoy_wrapper_driver_bind_support %lu %p", i
, pfOldSupport
);
959 return EFI_UNSUPPORTED
;
962 Status
= gBS
->HandleProtocol(ControllerHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevicePath
);
963 if (EFI_ERROR(Status
))
968 if (0 == CompareMem(gBlockData
.Path
, DevicePath
, gBlockData
.DevicePathCompareLen
))
970 debug("return EFI_UNSUPPORTED for ventoy");
971 return EFI_UNSUPPORTED
;
975 return pfOldSupport(This
, ControllerHandle
, RemainingDevicePath
);
978 EFI_STATUS
ventoy_disable_ex_filesystem(VOID
)
982 ventoy_find_filesystem_driverbind();
984 for (i
= 0; i
< g_DriverBindWrapperCnt
; i
++)
986 g_DriverBindWrapperList
[i
].DriverBinding
->Supported
= ventoy_wrapper_driver_bind_support
;
989 debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt
);
990 ventoy_debug_pause();
995 EFI_STATUS
ventoy_enable_ex_filesystem(VOID
)
999 for (i
= 0; i
< g_DriverBindWrapperCnt
; i
++)
1001 g_DriverBindWrapperList
[i
].DriverBinding
->Supported
= g_DriverBindWrapperList
[i
].pfOldSupport
;
1003 g_DriverBindWrapperCnt
= 0;
1008 EFI_STATUS EFIAPI ventoy_block_io_read_512
1010 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1013 IN UINTN BufferSize
,
1019 UINT8
*CurBuf
= NULL
;
1020 EFI_STATUS Status
= EFI_SUCCESS
;
1022 debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba
, BufferSize
/ 512, Buffer
);
1024 CurBuf
= (UINT8
*)Buffer
;
1029 Status
|= g_sector_2048_read(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1031 if (BufferSize
<= (4 - Mod
) * 512)
1033 CopyMem(CurBuf
, g_sector_buf
+ Mod
* 512, BufferSize
);
1038 ReadSize
= (4 - Mod
) * 512;
1039 CopyMem(CurBuf
, g_sector_buf
+ Mod
* 512, ReadSize
);
1042 BufferSize
-= ReadSize
;
1046 if (BufferSize
>= 2048)
1048 ReadSize
= BufferSize
/ 2048 * 2048;
1050 Status
|= g_sector_2048_read(This
, MediaId
, Lba
/ 4, ReadSize
, CurBuf
);
1053 Lba
+= ReadSize
/ 512;
1054 BufferSize
-= ReadSize
;
1059 Status
|= g_sector_2048_read(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1060 CopyMem(CurBuf
, g_sector_buf
, BufferSize
);
1066 EFI_STATUS EFIAPI ventoy_block_io_write_512
1068 IN EFI_BLOCK_IO_PROTOCOL
*This
,
1071 IN UINTN BufferSize
,
1077 UINT8
*CurBuf
= NULL
;
1078 EFI_STATUS Status
= EFI_SUCCESS
;
1080 debug("ventoy_block_io_write_512 %lu %lu\n", Lba
, BufferSize
/ 512);
1082 CurBuf
= (UINT8
*)Buffer
;
1087 Status
|= g_sector_2048_read(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1089 if (BufferSize
<= (4 - Mod
) * 512)
1091 CopyMem(g_sector_buf
+ Mod
* 512, CurBuf
, BufferSize
);
1092 return g_sector_2048_write(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1096 ReadSize
= (4 - Mod
) * 512;
1097 CopyMem(g_sector_buf
+ Mod
* 512, CurBuf
, ReadSize
);
1098 g_sector_2048_write(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1102 BufferSize
-= ReadSize
;
1106 if (BufferSize
>= 2048)
1108 ReadSize
= BufferSize
/ 2048 * 2048;
1110 Status
|= g_sector_2048_write(This
, MediaId
, Lba
/ 4, ReadSize
, CurBuf
);
1113 Lba
+= ReadSize
/ 512;
1114 BufferSize
-= ReadSize
;
1119 Status
|= g_sector_2048_read(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1121 CopyMem(g_sector_buf
, CurBuf
, BufferSize
);
1122 g_sector_2048_write(This
, MediaId
, Lba
/ 4, 2048, g_sector_buf
);
1128 EFI_STATUS EFIAPI
ventoy_install_blockio(IN EFI_HANDLE ImageHandle
, IN UINT64 ImgSize
)
1130 EFI_STATUS Status
= EFI_SUCCESS
;
1131 EFI_BLOCK_IO_PROTOCOL
*pBlockIo
= &(gBlockData
.BlockIo
);
1133 ventoy_fill_device_path();
1135 debug("install block io protocol %p", ImageHandle
);
1136 ventoy_debug_pause();
1140 gBlockData
.Media
.BlockSize
= 512;
1141 gBlockData
.Media
.LastBlock
= ImgSize
/ 512 - 1;
1142 gBlockData
.Media
.ReadOnly
= FALSE
;
1146 gBlockData
.Media
.BlockSize
= 2048;
1147 gBlockData
.Media
.LastBlock
= ImgSize
/ 2048 - 1;
1148 gBlockData
.Media
.ReadOnly
= TRUE
;
1151 gBlockData
.Media
.MediaPresent
= 1;
1152 gBlockData
.Media
.LogicalBlocksPerPhysicalBlock
= 1;
1154 pBlockIo
->Revision
= EFI_BLOCK_IO_PROTOCOL_REVISION3
;
1155 pBlockIo
->Media
= &(gBlockData
.Media
);
1156 pBlockIo
->Reset
= ventoy_block_io_reset
;
1160 g_sector_2048_read
= gMemdiskMode
? ventoy_block_io_ramdisk_read
: ventoy_block_io_read
;
1161 g_sector_2048_write
= gMemdiskMode
? ventoy_block_io_ramdisk_write
: ventoy_block_io_write
;
1162 pBlockIo
->ReadBlocks
= ventoy_block_io_read_512
;
1163 pBlockIo
->WriteBlocks
= ventoy_block_io_write_512
;
1167 pBlockIo
->ReadBlocks
= gMemdiskMode
? ventoy_block_io_ramdisk_read
: ventoy_block_io_read
;
1168 pBlockIo
->WriteBlocks
= ventoy_block_io_write
;
1171 pBlockIo
->FlushBlocks
= ventoy_block_io_flush
;
1173 Status
= gBS
->InstallMultipleProtocolInterfaces(&gBlockData
.Handle
,
1174 &gEfiBlockIoProtocolGuid
, &gBlockData
.BlockIo
,
1175 &gEfiDevicePathProtocolGuid
, gBlockData
.Path
,
1177 debug("Install protocol %r %p", Status
, gBlockData
.Handle
);
1178 if (EFI_ERROR(Status
))
1183 Status
= ventoy_connect_driver(gBlockData
.Handle
, L
"Disk I/O Driver");
1184 debug("Connect disk IO driver %r", Status
);
1186 Status
= ventoy_connect_driver(gBlockData
.Handle
, L
"Partition Driver");
1187 debug("Connect partition driver %r", Status
);
1188 if (EFI_ERROR(Status
))
1190 Status
= gBS
->ConnectController(gBlockData
.Handle
, NULL
, NULL
, TRUE
);
1191 debug("Connect all controller %r", Status
);
1194 ventoy_debug_pause();
1200 /* For file replace */
1203 STATIC EFI_STATUS EFIAPI
1204 ventoy_wrapper_fs_open(EFI_FILE_HANDLE This
, EFI_FILE_HANDLE
*New
, CHAR16
*Name
, UINT64 Mode
, UINT64 Attributes
)
1214 STATIC EFI_STATUS EFIAPI
1215 ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This
, EFI_FILE_HANDLE
*New
, CHAR16
*Name
, UINT64 Mode
, UINT64 Attributes
, EFI_FILE_IO_TOKEN
*Token
)
1217 return ventoy_wrapper_fs_open(This
, New
, Name
, Mode
, Attributes
);
1220 STATIC EFI_STATUS EFIAPI
1221 ventoy_wrapper_file_delete(EFI_FILE_HANDLE This
)
1227 STATIC EFI_STATUS EFIAPI
1228 ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This
, EFI_GUID
*Type
, UINTN Len
, VOID
*Data
)
1233 STATIC EFI_STATUS EFIAPI
1234 ventoy_wrapper_file_flush(EFI_FILE_HANDLE This
)
1241 STATIC EFI_STATUS EFIAPI
1242 ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This
, EFI_FILE_IO_TOKEN
*Token
)
1250 STATIC EFI_STATUS EFIAPI
1251 ventoy_wrapper_file_flush_ex_img0(EFI_FILE_HANDLE This
, EFI_FILE_IO_TOKEN
*Token
)
1258 STATIC EFI_STATUS EFIAPI
1259 ventoy_wrapper_file_flush_ex_img1(EFI_FILE_HANDLE This
, EFI_FILE_IO_TOKEN
*Token
)
1266 #define DEF_WRAP_FUNC(n) \
1267 STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_flush_ex_img#n(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) \
1271 return EFI_SUCCESS;\
1274 #define ITEM_WRAP_FUNC(n) ventoy_wrapper_file_flush_ex_img#n
1276 #if (VTOY_MAX_CONF_REPLACE > 2)
1279 #if (VTOY_MAX_CONF_REPLACE > 3)
1282 #if (VTOY_MAX_CONF_REPLACE > 4)
1285 #if (VTOY_MAX_CONF_REPLACE > 5)
1288 #if (VTOY_MAX_CONF_REPLACE > 6)
1291 #if (VTOY_MAX_CONF_REPLACE > 7)
1294 #if (VTOY_MAX_CONF_REPLACE > 8)
1295 #error "VTOY_MAX_CONF_REPLACE overflow"
1298 static EFI_FILE_FLUSH_EX g_img_flush_func
[VTOY_MAX_CONF_REPLACE
] =
1300 ventoy_wrapper_file_flush_ex_img0
,
1301 ventoy_wrapper_file_flush_ex_img1
,
1302 #if (VTOY_MAX_CONF_REPLACE > 2)
1305 #if (VTOY_MAX_CONF_REPLACE > 3)
1308 #if (VTOY_MAX_CONF_REPLACE > 4)
1311 #if (VTOY_MAX_CONF_REPLACE > 5)
1314 #if (VTOY_MAX_CONF_REPLACE > 6)
1317 #if (VTOY_MAX_CONF_REPLACE > 7)
1322 STATIC ventoy_efi_file_replace
*ventoy_wrapper_get_replace(EFI_FILE_HANDLE This
)
1326 if (This
->FlushEx
== ventoy_wrapper_file_flush_ex
)
1328 return &g_efi_file_replace
;
1331 for (i
= 0; i
< VTOY_MAX_CONF_REPLACE
; i
++)
1333 if (This
->FlushEx
== g_img_flush_func
[i
])
1335 return g_img_file_replace
+ i
;
1342 STATIC EFI_STATUS EFIAPI
1343 ventoy_wrapper_file_write(EFI_FILE_HANDLE This
, UINTN
*Len
, VOID
*Data
)
1349 return EFI_WRITE_PROTECTED
;
1352 STATIC EFI_STATUS EFIAPI
1353 ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL
*This
, IN OUT EFI_FILE_IO_TOKEN
*Token
)
1355 return ventoy_wrapper_file_write(This
, &(Token
->BufferSize
), Token
->Buffer
);
1359 STATIC EFI_STATUS EFIAPI
1360 ventoy_wrapper_file_close(EFI_FILE_HANDLE This
)
1366 STATIC EFI_STATUS EFIAPI
1367 ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This
, UINT64 Position
)
1369 ventoy_efi_file_replace
*replace
= NULL
;
1371 replace
= ventoy_wrapper_get_replace(This
);
1373 if (Position
<= replace
->FileSizeBytes
)
1375 replace
->CurPos
= Position
;
1379 replace
->CurPos
= replace
->FileSizeBytes
;
1385 STATIC EFI_STATUS EFIAPI
1386 ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This
, UINT64
*Position
)
1388 ventoy_efi_file_replace
*replace
= NULL
;
1390 replace
= ventoy_wrapper_get_replace(This
);
1392 *Position
= replace
->CurPos
;
1398 STATIC EFI_STATUS EFIAPI
1399 ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This
, EFI_GUID
*Type
, UINTN
*Len
, VOID
*Data
)
1401 EFI_FILE_INFO
*Info
= (EFI_FILE_INFO
*) Data
;
1402 ventoy_efi_file_replace
*replace
= NULL
;
1404 replace
= ventoy_wrapper_get_replace(This
);
1406 debug("ventoy_wrapper_file_get_info ... %u", *Len
);
1408 if (!CompareGuid(Type
, &gEfiFileInfoGuid
))
1410 return EFI_INVALID_PARAMETER
;
1416 return EFI_BUFFER_TOO_SMALL
;
1419 ZeroMem(Data
, sizeof(EFI_FILE_INFO
));
1421 Info
->Size
= sizeof(EFI_FILE_INFO
);
1422 Info
->FileSize
= replace
->FileSizeBytes
;
1423 Info
->PhysicalSize
= replace
->FileSizeBytes
;
1424 Info
->Attribute
= EFI_FILE_READ_ONLY
;
1425 //Info->FileName = EFI_FILE_READ_ONLY;
1432 STATIC EFI_STATUS EFIAPI
1433 ventoy_wrapper_file_read(EFI_FILE_HANDLE This
, UINTN
*Len
, VOID
*Data
)
1436 UINTN ReadLen
= *Len
;
1437 ventoy_efi_file_replace
*replace
= NULL
;
1439 replace
= ventoy_wrapper_get_replace(This
);
1441 debug("ventoy_wrapper_file_read ... %u", *Len
);
1443 if (replace
->CurPos
+ ReadLen
> replace
->FileSizeBytes
)
1445 ReadLen
= replace
->FileSizeBytes
- replace
->CurPos
;
1448 Lba
= replace
->CurPos
/ 2048 + replace
->BlockIoSectorStart
;
1450 ventoy_block_io_read(NULL
, 0, Lba
, ReadLen
, Data
);
1454 replace
->CurPos
+= ReadLen
;
1459 STATIC EFI_STATUS EFIAPI
1460 ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL
*This
, IN OUT EFI_FILE_IO_TOKEN
*Token
)
1462 return ventoy_wrapper_file_read(This
, &(Token
->BufferSize
), Token
->Buffer
);
1465 STATIC EFI_STATUS EFIAPI
ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL
*File
, BOOLEAN Img
, UINTN Index
)
1467 File
->Revision
= EFI_FILE_PROTOCOL_REVISION2
;
1468 File
->Open
= ventoy_wrapper_fs_open
;
1469 File
->Close
= ventoy_wrapper_file_close
;
1470 File
->Delete
= ventoy_wrapper_file_delete
;
1471 File
->Read
= ventoy_wrapper_file_read
;
1472 File
->Write
= ventoy_wrapper_file_write
;
1473 File
->GetPosition
= ventoy_wrapper_file_get_pos
;
1474 File
->SetPosition
= ventoy_wrapper_file_set_pos
;
1475 File
->GetInfo
= ventoy_wrapper_file_get_info
;
1476 File
->SetInfo
= ventoy_wrapper_file_set_info
;
1477 File
->Flush
= ventoy_wrapper_file_flush
;
1478 File
->OpenEx
= ventoy_wrapper_file_open_ex
;
1479 File
->ReadEx
= ventoy_wrapper_file_read_ex
;
1480 File
->WriteEx
= ventoy_wrapper_file_write_ex
;
1484 File
->FlushEx
= g_img_flush_func
[Index
];
1488 File
->FlushEx
= ventoy_wrapper_file_flush_ex
;
1494 STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open
1496 EFI_FILE_HANDLE This
,
1497 EFI_FILE_HANDLE
*New
,
1506 EFI_STATUS Status
= EFI_SUCCESS
;
1509 ventoy_virt_chunk
*virt
= NULL
;
1510 ventoy_grub_param_file_replace
*replace
= NULL
;
1512 debug("## ventoy_wrapper_file_open <%s> ", Name
);
1514 if ((Mode
& EFI_FILE_MODE_WRITE
) > 0 && StrCmp(Name
, L
"\\loader\\random-seed") == 0)
1518 debug("## ventoy_wrapper_file_open return NOT_FOUND for random-seed %lx", Mode
);
1521 return EFI_NOT_FOUND
;
1524 Status
= g_original_fopen(This
, New
, Name
, Mode
, Attributes
);
1525 if (EFI_ERROR(Status
))
1531 if (g_file_replace_list
&& g_file_replace_list
->magic
== GRUB_FILE_REPLACE_MAGIC
&&
1532 g_file_replace_list
->new_file_virtual_id
< g_virt_chunk_num
)
1534 AsciiSPrint(TmpName
, sizeof(TmpName
), "%s", Name
);
1535 for (j
= 0; j
< 4; j
++)
1537 if (0 == AsciiStriCmp(g_file_replace_list
[i
].old_file_name
[j
], TmpName
))
1539 g_original_fclose(*New
);
1540 *New
= &g_efi_file_replace
.WrapperHandle
;
1541 ventoy_wrapper_file_procotol(*New
, FALSE
, 0);
1543 virt
= g_virt_chunk
+ g_file_replace_list
->new_file_virtual_id
;
1545 Sectors
= (virt
->mem_sector_end
- virt
->mem_sector_start
) + (virt
->remap_sector_end
- virt
->remap_sector_start
);
1547 g_efi_file_replace
.BlockIoSectorStart
= virt
->mem_sector_start
;
1548 g_efi_file_replace
.FileSizeBytes
= Sectors
* 2048;
1552 debug("## ventoy_wrapper_file_open <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name
,
1553 g_efi_file_replace
.BlockIoSectorStart
, Sectors
, Sectors
* 2048);
1561 if (StrCmp(Name
, L
"\\EFI\\BOOT") == 0)
1563 (*New
)->Open
= ventoy_wrapper_file_open
;
1567 for (i
= 0; g_img_replace_list
&& i
< VTOY_MAX_CONF_REPLACE
; i
++)
1569 replace
= g_img_replace_list
+ i
;
1570 if (replace
->magic
!= GRUB_IMG_REPLACE_MAGIC
|| replace
->new_file_virtual_id
>= g_virt_chunk_num
)
1575 AsciiSPrint(TmpName
, sizeof(TmpName
), "%s", Name
);
1576 for (j
= 0; j
< replace
->old_file_cnt
; j
++)
1578 AsciiStrCpyS(OldName
, sizeof(OldName
), replace
->old_file_name
[j
]);
1579 if ((0 == AsciiStrCmp(OldName
, TmpName
)) ||
1580 (AsciiStrnCmp(OldName
, "\\loader\\entries\\", 16) == 0 &&
1581 AsciiStrCmp(OldName
+ 16, TmpName
) == 0
1585 g_original_fclose(*New
);
1586 *New
= &(g_img_file_replace
[i
].WrapperHandle
);
1587 ventoy_wrapper_file_procotol(*New
, TRUE
, i
);
1589 virt
= g_virt_chunk
+ replace
->new_file_virtual_id
;
1591 Sectors
= (virt
->mem_sector_end
- virt
->mem_sector_start
) + (virt
->remap_sector_end
- virt
->remap_sector_start
);
1593 g_img_file_replace
[i
].BlockIoSectorStart
= virt
->mem_sector_start
;
1594 g_img_file_replace
[i
].FileSizeBytes
= Sectors
* 2048;
1598 debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name
,
1599 g_img_file_replace
[i
].BlockIoSectorStart
, Sectors
, Sectors
* 2048);
1608 if (g_img_replace_list
&& StrCmp(Name
, L
"\\loader\\entries") == 0)
1610 (*New
)->Open
= ventoy_wrapper_file_open
;
1616 EFI_STATUS EFIAPI ventoy_wrapper_open_volume
1618 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
1619 OUT EFI_FILE_PROTOCOL
**Root
1622 EFI_STATUS Status
= EFI_SUCCESS
;
1624 Status
= g_original_open_volume(This
, Root
);
1625 if (!EFI_ERROR(Status
))
1627 g_original_fopen
= (*Root
)->Open
;
1628 g_original_fclose
= (*Root
)->Close
;
1629 (*Root
)->Open
= ventoy_wrapper_file_open
;
1635 EFI_STATUS EFIAPI
ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume
)
1637 g_original_open_volume
= OpenVolume
;
1642 /* For auto skip Windows 'Press any key to boot from CD or DVD ...' */
1645 STATIC EFI_STATUS EFIAPI ventoy_wrapper_read_key_ex
1647 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
1648 OUT EFI_KEY_DATA
*KeyData
1651 /* only hook once before BCD file read */
1652 if (g_keyboard_hook_count
== 0 && g_blockio_bcd_read_done
== FALSE
)
1654 g_keyboard_hook_count
++;
1656 KeyData
->Key
.ScanCode
= SCAN_DELETE
;
1657 KeyData
->Key
.UnicodeChar
= 0;
1658 KeyData
->KeyState
.KeyShiftState
= 0;
1659 KeyData
->KeyState
.KeyToggleState
= 0;
1664 return g_org_read_key_ex(This
, KeyData
);
1667 EFI_STATUS EFIAPI ventoy_wrapper_read_key
1669 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
1670 OUT EFI_INPUT_KEY
*Key
1673 /* only hook once before BCD file read */
1674 if (g_keyboard_hook_count
== 0 && g_blockio_bcd_read_done
== FALSE
)
1676 g_keyboard_hook_count
++;
1678 Key
->ScanCode
= SCAN_DELETE
;
1679 Key
->UnicodeChar
= 0;
1683 return g_org_read_key(This
, Key
);
1686 EFI_STATUS
ventoy_hook_keyboard_start(VOID
)
1688 g_blockio_start_record_bcd
= TRUE
;
1689 g_blockio_bcd_read_done
= FALSE
;
1690 g_keyboard_hook_count
= 0;
1692 if (g_con_simple_input_ex
)
1694 g_org_read_key_ex
= g_con_simple_input_ex
->ReadKeyStrokeEx
;
1695 g_con_simple_input_ex
->ReadKeyStrokeEx
= ventoy_wrapper_read_key_ex
;
1698 g_org_read_key
= gST
->ConIn
->ReadKeyStroke
;
1699 gST
->ConIn
->ReadKeyStroke
= ventoy_wrapper_read_key
;
1704 EFI_STATUS
ventoy_hook_keyboard_stop(VOID
)
1706 g_blockio_start_record_bcd
= FALSE
;
1707 g_blockio_bcd_read_done
= FALSE
;
1708 g_keyboard_hook_count
= 0;
1710 if (g_con_simple_input_ex
)
1712 g_con_simple_input_ex
->ReadKeyStrokeEx
= g_org_read_key_ex
;
1715 gST
->ConIn
->ReadKeyStroke
= g_org_read_key
;
1721 /* Fixup the 1st cdrom influnce for Windows boot */
1724 STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle
1726 IN EFI_LOCATE_SEARCH_TYPE SearchType
,
1727 IN EFI_GUID
*Protocol
, OPTIONAL
1728 IN VOID
*SearchKey
, OPTIONAL
1729 IN OUT UINTN
*BufferSize
,
1730 OUT EFI_HANDLE
*Buffer
1734 EFI_HANDLE Handle
= NULL
;
1735 EFI_STATUS Status
= EFI_SUCCESS
;
1737 Status
= g_org_locate_handle(SearchType
, Protocol
, SearchKey
, BufferSize
, Buffer
);
1739 if (EFI_SUCCESS
== Status
&& Protocol
&& CompareGuid(&gEfiBlockIoProtocolGuid
, Protocol
))
1741 for (i
= 0; i
< (*BufferSize
) / sizeof(EFI_HANDLE
); i
++)
1743 if (Buffer
[i
] == gBlockData
.Handle
)
1746 Buffer
[0] = Buffer
[i
];
1756 EFI_STATUS
ventoy_hook_1st_cdrom_start(VOID
)
1758 g_org_locate_handle
= gBS
->LocateHandle
;
1759 gBS
->LocateHandle
= ventoy_wrapper_locate_handle
;
1764 EFI_STATUS
ventoy_hook_1st_cdrom_stop(VOID
)
1766 gBS
->LocateHandle
= g_org_locate_handle
;
1767 g_org_locate_handle
= NULL
;