mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-05-09 13:42:03 -04:00
1.0.07 release
This commit is contained in:
parent
d551fc2e3c
commit
d5b829f8e8
52 changed files with 1770 additions and 154 deletions
|
@ -53,15 +53,27 @@ ventoy_sector_flag *g_sector_flag = NULL;
|
|||
UINT32 g_sector_flag_num = 0;
|
||||
static grub_env_get_pf grub_env_get = NULL;
|
||||
|
||||
EFI_FILE_OPEN g_original_fopen = NULL;
|
||||
EFI_FILE_CLOSE g_original_fclose = NULL;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME g_original_open_volume = NULL;
|
||||
|
||||
ventoy_grub_param_file_replace *g_file_replace_list = NULL;
|
||||
ventoy_efi_file_replace g_efi_file_replace;
|
||||
|
||||
CHAR16 gFirstTryBootFile[256] = {0};
|
||||
|
||||
CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH;
|
||||
|
||||
/* Boot filename */
|
||||
UINTN gBootFileStartIndex = 1;
|
||||
CONST CHAR16 *gEfiBootFileName[] =
|
||||
{
|
||||
L"@",
|
||||
EFI_REMOVABLE_MEDIA_FILE_NAME,
|
||||
L"\\EFI\\BOOT\\GRUBX64.EFI",
|
||||
L"\\EFI\\BOOT\\BOOTx64.EFI",
|
||||
L"\\EFI\\BOOT\\bootx64.efi",
|
||||
L"\\efi\\boot\\bootx64.efi",
|
||||
};
|
||||
|
||||
/* EFI block device vendor device path GUID */
|
||||
|
@ -886,6 +898,7 @@ static int ventoy_update_image_location(ventoy_os_param *param)
|
|||
STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
UINT32 i = 0;
|
||||
UINT32 old_cnt = 0;
|
||||
UINTN size = 0;
|
||||
UINT8 chksum = 0;
|
||||
CHAR16 *pPos = NULL;
|
||||
|
@ -915,8 +928,33 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||
gLoadIsoEfi = TRUE;
|
||||
}
|
||||
|
||||
pPos = StrStr(pCmdLine, L"FirstTry=@");
|
||||
if (pPos)
|
||||
{
|
||||
pPos += StrLen(L"FirstTry=");
|
||||
for (i = 0; i < ARRAY_SIZE(gFirstTryBootFile); i++, pPos++)
|
||||
{
|
||||
if (*pPos != L' ' && *pPos != L'\t' && *pPos)
|
||||
{
|
||||
gFirstTryBootFile[i] = (*pPos == '@') ? '\\' : *pPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gEfiBootFileName[0] = gFirstTryBootFile;
|
||||
gBootFileStartIndex = 0;
|
||||
}
|
||||
|
||||
debug("cmdline:<%s>", pCmdLine);
|
||||
|
||||
if (gFirstTryBootFile[0])
|
||||
{
|
||||
debug("First Try:<%s>", gFirstTryBootFile);
|
||||
}
|
||||
|
||||
pPos = StrStr(pCmdLine, L"env_param=");
|
||||
if (!pPos)
|
||||
{
|
||||
|
@ -926,6 +964,18 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle)
|
|||
pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param="));
|
||||
grub_env_get = pGrubParam->grub_env_get;
|
||||
|
||||
g_file_replace_list = &pGrubParam->file_replace;
|
||||
old_cnt = g_file_replace_list->old_file_cnt;
|
||||
debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>",
|
||||
g_file_replace_list->magic,
|
||||
g_file_replace_list->new_file_virtual_id,
|
||||
old_cnt,
|
||||
old_cnt > 0 ? g_file_replace_list->old_file_name[0] : "",
|
||||
old_cnt > 1 ? g_file_replace_list->old_file_name[1] : "",
|
||||
old_cnt > 2 ? g_file_replace_list->old_file_name[2] : "",
|
||||
old_cnt > 3 ? g_file_replace_list->old_file_name[3] : ""
|
||||
);
|
||||
|
||||
pPos = StrStr(pCmdLine, L"mem:");
|
||||
g_chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4);
|
||||
|
||||
|
@ -970,8 +1020,85 @@ 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
|
||||
)
|
||||
{
|
||||
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_boot(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
UINTN t = 0;
|
||||
UINTN i = 0;
|
||||
UINTN j = 0;
|
||||
UINTN Find = 0;
|
||||
|
@ -982,78 +1109,99 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
|
|||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
|
||||
EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
|
||||
for (t = 0; t < 3; t++)
|
||||
{
|
||||
Count = 0;
|
||||
Handles = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
debug("ventoy_boot fs count:%u", Count);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
return Status;
|
||||
}
|
||||
|
||||
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("ventoy_boot fs count:%u", Count);
|
||||
|
||||
debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE));
|
||||
if (CompareMem(gBlockData.Path, pDevPath, gBlockData.DevicePathCompareLen))
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
debug("Not ventoy disk file system");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(gEfiBootFileName); j++)
|
||||
{
|
||||
Status = ventoy_load_image(ImageHandle, pDevPath, gEfiBootFileName[j],
|
||||
StrSize(gEfiBootFileName[j]), &Image);
|
||||
if (EFI_SUCCESS == Status)
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume);
|
||||
|
||||
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));
|
||||
if (CompareMem(gBlockData.Path, pDevPath, gBlockData.DevicePathCompareLen))
|
||||
{
|
||||
debug("Not ventoy disk file system");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = gBootFileStartIndex; j < ARRAY_SIZE(gEfiBootFileName); j++)
|
||||
{
|
||||
Status = ventoy_load_image(ImageHandle, pDevPath, gEfiBootFileName[j],
|
||||
StrSize(gEfiBootFileName[j]), &Image);
|
||||
if (EFI_SUCCESS == Status)
|
||||
{
|
||||
break;
|
||||
}
|
||||
debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]);
|
||||
}
|
||||
|
||||
if (j >= ARRAY_SIZE(gEfiBootFileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Find++;
|
||||
debug("Find boot file, now try to boot .....");
|
||||
ventoy_debug_pause();
|
||||
|
||||
if (gDebugPrint)
|
||||
{
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||
//ventoy_wrapper_system();
|
||||
}
|
||||
|
||||
if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC)
|
||||
{
|
||||
g_original_open_volume = pFile->OpenVolume;
|
||||
pFile->OpenVolume = ventoy_wrapper_open_volume;
|
||||
}
|
||||
|
||||
Status = gBS->StartImage(Image, NULL, NULL);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
debug("Failed to start image %r", Status);
|
||||
sleep(3);
|
||||
gBS->UnloadImage(Image);
|
||||
break;
|
||||
}
|
||||
debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]);
|
||||
}
|
||||
|
||||
if (j >= ARRAY_SIZE(gEfiBootFileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
FreePool(Handles);
|
||||
|
||||
Find++;
|
||||
debug("Find boot file, now try to boot .....");
|
||||
ventoy_debug_pause();
|
||||
|
||||
if (gDebugPrint)
|
||||
if (Find == 0)
|
||||
{
|
||||
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||
}
|
||||
|
||||
Status = gBS->StartImage(Image, NULL, NULL);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
debug("Failed to start image %r", Status);
|
||||
sleep(3);
|
||||
gBS->UnloadImage(Image);
|
||||
break;
|
||||
debug("Fs not found, now wait and retry...");
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
|
||||
FreePool(Handles);
|
||||
|
||||
if (Find == 0)
|
||||
{
|
||||
return EFI_NOT_FOUND;
|
||||
|
@ -1190,9 +1338,21 @@ EFI_STATUS EFIAPI VentoyEfiMain
|
|||
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);
|
||||
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();
|
||||
|
|
|
@ -205,6 +205,7 @@ typedef struct 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__)
|
||||
#define sleep(sec) gBS->Stall(1000000 * (sec))
|
||||
|
||||
#define ventoy_debug_pause() \
|
||||
|
@ -219,9 +220,32 @@ if (gDebugPrint) \
|
|||
typedef const char * (*grub_env_get_pf)(const char *name);
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
|
||||
|
||||
typedef struct ventoy_efi_file_replace
|
||||
{
|
||||
UINT64 BlockIoSectorStart;
|
||||
|
||||
UINT64 CurPos;
|
||||
UINT64 FileSizeBytes;
|
||||
|
||||
EFI_FILE_PROTOCOL WrapperHandle;
|
||||
}ventoy_efi_file_replace;
|
||||
|
||||
typedef struct ventoy_grub_param_file_replace
|
||||
{
|
||||
UINT32 magic;
|
||||
char old_file_name[4][256];
|
||||
UINT32 old_file_cnt;
|
||||
UINT32 new_file_virtual_id;
|
||||
}ventoy_grub_param_file_replace;
|
||||
|
||||
typedef struct ventoy_grub_param
|
||||
{
|
||||
grub_env_get_pf grub_env_get;
|
||||
|
||||
ventoy_grub_param_file_replace file_replace;
|
||||
}ventoy_grub_param;
|
||||
|
||||
typedef struct ventoy_ram_disk
|
||||
|
@ -233,8 +257,44 @@ typedef struct ventoy_ram_disk
|
|||
#pragma pack()
|
||||
|
||||
|
||||
typedef struct well_known_guid
|
||||
{
|
||||
EFI_GUID *guid;
|
||||
const char *name;
|
||||
}well_known_guid;
|
||||
|
||||
typedef struct ventoy_system_wrapper
|
||||
{
|
||||
EFI_LOCATE_PROTOCOL NewLocateProtocol;
|
||||
EFI_LOCATE_PROTOCOL OriLocateProtocol;
|
||||
|
||||
EFI_HANDLE_PROTOCOL NewHandleProtocol;
|
||||
EFI_HANDLE_PROTOCOL OriHandleProtocol;
|
||||
|
||||
EFI_OPEN_PROTOCOL NewOpenProtocol;
|
||||
EFI_OPEN_PROTOCOL OriOpenProtocol;
|
||||
} ventoy_system_wrapper;
|
||||
|
||||
#define ventoy_wrapper(bs, wrapper, func, newfunc) \
|
||||
{\
|
||||
wrapper.Ori##func = bs->func;\
|
||||
wrapper.New##func = newfunc;\
|
||||
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);
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File);
|
||||
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
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
[Sources]
|
||||
Ventoy.h
|
||||
Ventoy.c
|
||||
VentoyDebug.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -42,6 +43,7 @@
|
|||
[Guids]
|
||||
gShellVariableGuid
|
||||
gEfiVirtualCdGuid
|
||||
gEfiFileInfoGuid
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid
|
||||
|
@ -49,3 +51,30 @@
|
|||
gEfiDevicePathProtocolGuid
|
||||
gEfiSimpleFileSystemProtocolGuid
|
||||
gEfiRamDiskProtocolGuid
|
||||
gEfiAbsolutePointerProtocolGuid
|
||||
gEfiAcpiTableProtocolGuid
|
||||
gEfiBlockIo2ProtocolGuid
|
||||
gEfiBusSpecificDriverOverrideProtocolGuid
|
||||
gEfiComponentNameProtocolGuid
|
||||
gEfiComponentName2ProtocolGuid
|
||||
gEfiDriverBindingProtocolGuid
|
||||
gEfiDiskIoProtocolGuid
|
||||
gEfiDiskIo2ProtocolGuid
|
||||
gEfiGraphicsOutputProtocolGuid
|
||||
gEfiHiiConfigAccessProtocolGuid
|
||||
gEfiHiiFontProtocolGuid
|
||||
gEfiLoadFileProtocolGuid
|
||||
gEfiLoadFile2ProtocolGuid
|
||||
gEfiLoadedImageProtocolGuid
|
||||
gEfiLoadedImageDevicePathProtocolGuid
|
||||
gEfiPciIoProtocolGuid
|
||||
gEfiSerialIoProtocolGuid
|
||||
gEfiSimpleTextInProtocolGuid
|
||||
gEfiSimpleTextInputExProtocolGuid
|
||||
gEfiSimpleTextOutProtocolGuid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,325 @@
|
|||
/******************************************************************************
|
||||
* 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>
|
||||
|
||||
STATIC ventoy_system_wrapper g_system_wrapper;
|
||||
|
||||
static struct well_known_guid g_efi_well_known_guids[] =
|
||||
{
|
||||
{ &gEfiAbsolutePointerProtocolGuid, "AbsolutePointer" },
|
||||
{ &gEfiAcpiTableProtocolGuid, "AcpiTable" },
|
||||
{ &gEfiBlockIoProtocolGuid, "BlockIo" },
|
||||
{ &gEfiBlockIo2ProtocolGuid, "BlockIo2" },
|
||||
{ &gEfiBusSpecificDriverOverrideProtocolGuid, "BusSpecificDriverOverride" },
|
||||
{ &gEfiComponentNameProtocolGuid, "ComponentName" },
|
||||
{ &gEfiComponentName2ProtocolGuid, "ComponentName2" },
|
||||
{ &gEfiDevicePathProtocolGuid, "DevicePath" },
|
||||
{ &gEfiDriverBindingProtocolGuid, "DriverBinding" },
|
||||
{ &gEfiDiskIoProtocolGuid, "DiskIo" },
|
||||
{ &gEfiDiskIo2ProtocolGuid, "DiskIo2" },
|
||||
{ &gEfiGraphicsOutputProtocolGuid, "GraphicsOutput" },
|
||||
{ &gEfiHiiConfigAccessProtocolGuid, "HiiConfigAccess" },
|
||||
{ &gEfiHiiFontProtocolGuid, "HiiFont" },
|
||||
{ &gEfiLoadFileProtocolGuid, "LoadFile" },
|
||||
{ &gEfiLoadFile2ProtocolGuid, "LoadFile2" },
|
||||
{ &gEfiLoadedImageProtocolGuid, "LoadedImage" },
|
||||
{ &gEfiLoadedImageDevicePathProtocolGuid, "LoadedImageDevicePath"},
|
||||
{ &gEfiPciIoProtocolGuid, "PciIo" },
|
||||
{ &gEfiSerialIoProtocolGuid, "SerialIo" },
|
||||
{ &gEfiSimpleFileSystemProtocolGuid, "SimpleFileSystem" },
|
||||
{ &gEfiSimpleTextInProtocolGuid, "SimpleTextInput" },
|
||||
{ &gEfiSimpleTextInputExProtocolGuid, "SimpleTextInputEx" },
|
||||
{ &gEfiSimpleTextOutProtocolGuid, "SimpleTextOutput" },
|
||||
};
|
||||
|
||||
STATIC CHAR8 gEfiGuidName[128];
|
||||
|
||||
static const char * ventoy_get_guid_name(EFI_GUID *guid)
|
||||
{
|
||||
UINTN i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_efi_well_known_guids); i++)
|
||||
{
|
||||
if (CompareGuid(g_efi_well_known_guids[i].guid, guid))
|
||||
{
|
||||
return g_efi_well_known_guids[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
AsciiSPrint(gEfiGuidName, sizeof(gEfiGuidName), "%g", guid);
|
||||
return gEfiGuidName;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_delete(EFI_FILE_HANDLE This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_flush(EFI_FILE_HANDLE This)
|
||||
{
|
||||
(VOID)This;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Ex version */
|
||||
EFI_STATUS EFIAPI
|
||||
ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
|
||||
{
|
||||
(VOID)This;
|
||||
(VOID)Token;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
g_efi_file_replace.CurPos = Position;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_handle_protocol
|
||||
(
|
||||
IN EFI_HANDLE Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
OUT VOID **Interface
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
Status = g_system_wrapper.OriHandleProtocol(Handle, Protocol, Interface);
|
||||
|
||||
if (CompareGuid(Protocol, &gEfiSimpleFileSystemProtocolGuid))
|
||||
{
|
||||
EFI_FILE_PROTOCOL *FileProtocol = NULL;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **)(Interface));
|
||||
|
||||
pFile->OpenVolume(pFile, &FileProtocol);
|
||||
|
||||
debug("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
|
||||
pFile, pFile->OpenVolume, FileProtocol, FileProtocol->Open);
|
||||
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_open_protocol
|
||||
(
|
||||
IN EFI_HANDLE Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
OUT VOID **Interface, OPTIONAL
|
||||
IN EFI_HANDLE AgentHandle,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINT32 Attributes
|
||||
)
|
||||
{
|
||||
debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes);
|
||||
}
|
||||
|
||||
STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
|
||||
(
|
||||
IN EFI_GUID *Protocol,
|
||||
IN VOID *Registration, OPTIONAL
|
||||
OUT VOID **Interface
|
||||
)
|
||||
{
|
||||
debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol));
|
||||
return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface);
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID)
|
||||
{
|
||||
ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol);
|
||||
ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue