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>
39 STATIC ventoy_system_wrapper g_system_wrapper
;
41 static struct well_known_guid g_efi_well_known_guids
[] =
43 { &gEfiAbsolutePointerProtocolGuid
, "AbsolutePointer" },
44 { &gEfiAcpiTableProtocolGuid
, "AcpiTable" },
45 { &gEfiBlockIoProtocolGuid
, "BlockIo" },
46 { &gEfiBlockIo2ProtocolGuid
, "BlockIo2" },
47 { &gEfiBusSpecificDriverOverrideProtocolGuid
, "BusSpecificDriverOverride" },
48 { &gEfiComponentNameProtocolGuid
, "ComponentName" },
49 { &gEfiComponentName2ProtocolGuid
, "ComponentName2" },
50 { &gEfiDevicePathProtocolGuid
, "DevicePath" },
51 { &gEfiDriverBindingProtocolGuid
, "DriverBinding" },
52 { &gEfiDiskIoProtocolGuid
, "DiskIo" },
53 { &gEfiDiskIo2ProtocolGuid
, "DiskIo2" },
54 { &gEfiGraphicsOutputProtocolGuid
, "GraphicsOutput" },
55 { &gEfiHiiConfigAccessProtocolGuid
, "HiiConfigAccess" },
56 { &gEfiHiiFontProtocolGuid
, "HiiFont" },
57 { &gEfiLoadFileProtocolGuid
, "LoadFile" },
58 { &gEfiLoadFile2ProtocolGuid
, "LoadFile2" },
59 { &gEfiLoadedImageProtocolGuid
, "LoadedImage" },
60 { &gEfiLoadedImageDevicePathProtocolGuid
, "LoadedImageDevicePath"},
61 { &gEfiPciIoProtocolGuid
, "PciIo" },
62 { &gEfiSerialIoProtocolGuid
, "SerialIo" },
63 { &gEfiSimpleFileSystemProtocolGuid
, "SimpleFileSystem" },
64 { &gEfiSimpleTextInProtocolGuid
, "SimpleTextInput" },
65 { &gEfiSimpleTextInputExProtocolGuid
, "SimpleTextInputEx" },
66 { &gEfiSimpleTextOutProtocolGuid
, "SimpleTextOutput" },
69 STATIC CHAR8 gEfiGuidName
[128];
71 static const char * ventoy_get_guid_name(EFI_GUID
*guid
)
75 for (i
= 0; i
< ARRAY_SIZE(g_efi_well_known_guids
); i
++)
77 if (CompareGuid(g_efi_well_known_guids
[i
].guid
, guid
))
79 return g_efi_well_known_guids
[i
].name
;
83 AsciiSPrint(gEfiGuidName
, sizeof(gEfiGuidName
), "%g", guid
);
88 ventoy_wrapper_fs_open(EFI_FILE_HANDLE This
, EFI_FILE_HANDLE
*New
, CHAR16
*Name
, UINT64 Mode
, UINT64 Attributes
)
99 ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This
, EFI_FILE_HANDLE
*New
, CHAR16
*Name
, UINT64 Mode
, UINT64 Attributes
, EFI_FILE_IO_TOKEN
*Token
)
101 return ventoy_wrapper_fs_open(This
, New
, Name
, Mode
, Attributes
);
105 ventoy_wrapper_file_delete(EFI_FILE_HANDLE This
)
112 ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This
, EFI_GUID
*Type
, UINTN Len
, VOID
*Data
)
118 ventoy_wrapper_file_flush(EFI_FILE_HANDLE This
)
126 ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This
, EFI_FILE_IO_TOKEN
*Token
)
135 ventoy_wrapper_file_write(EFI_FILE_HANDLE This
, UINTN
*Len
, VOID
*Data
)
141 return EFI_WRITE_PROTECTED
;
145 ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL
*This
, IN OUT EFI_FILE_IO_TOKEN
*Token
)
147 return ventoy_wrapper_file_write(This
, &(Token
->BufferSize
), Token
->Buffer
);
151 static EFI_STATUS EFIAPI
152 ventoy_wrapper_file_close(EFI_FILE_HANDLE This
)
159 static EFI_STATUS EFIAPI
160 ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This
, UINT64 Position
)
164 g_efi_file_replace
.CurPos
= Position
;
168 static EFI_STATUS EFIAPI
169 ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This
, UINT64
*Position
)
173 *Position
= g_efi_file_replace
.CurPos
;
179 static EFI_STATUS EFIAPI
180 ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This
, EFI_GUID
*Type
, UINTN
*Len
, VOID
*Data
)
182 EFI_FILE_INFO
*Info
= (EFI_FILE_INFO
*) Data
;
184 debug("ventoy_wrapper_file_get_info ... %u", *Len
);
186 if (!CompareGuid(Type
, &gEfiFileInfoGuid
))
188 return EFI_INVALID_PARAMETER
;
194 return EFI_BUFFER_TOO_SMALL
;
197 ZeroMem(Data
, sizeof(EFI_FILE_INFO
));
199 Info
->Size
= sizeof(EFI_FILE_INFO
);
200 Info
->FileSize
= g_efi_file_replace
.FileSizeBytes
;
201 Info
->PhysicalSize
= g_efi_file_replace
.FileSizeBytes
;
202 Info
->Attribute
= EFI_FILE_READ_ONLY
;
203 //Info->FileName = EFI_FILE_READ_ONLY;
210 static EFI_STATUS EFIAPI
211 ventoy_wrapper_file_read(EFI_FILE_HANDLE This
, UINTN
*Len
, VOID
*Data
)
214 UINTN ReadLen
= *Len
;
218 debug("ventoy_wrapper_file_read ... %u", *Len
);
220 if (g_efi_file_replace
.CurPos
+ ReadLen
> g_efi_file_replace
.FileSizeBytes
)
222 ReadLen
= g_efi_file_replace
.FileSizeBytes
- g_efi_file_replace
.CurPos
;
225 Lba
= g_efi_file_replace
.CurPos
/ 2048 + g_efi_file_replace
.BlockIoSectorStart
;
227 ventoy_block_io_read(NULL
, 0, Lba
, ReadLen
, Data
);
231 g_efi_file_replace
.CurPos
+= ReadLen
;
238 ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL
*This
, IN OUT EFI_FILE_IO_TOKEN
*Token
)
240 return ventoy_wrapper_file_read(This
, &(Token
->BufferSize
), Token
->Buffer
);
243 EFI_STATUS EFIAPI
ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL
*File
)
245 File
->Revision
= EFI_FILE_PROTOCOL_REVISION2
;
246 File
->Open
= ventoy_wrapper_fs_open
;
247 File
->Close
= ventoy_wrapper_file_close
;
248 File
->Delete
= ventoy_wrapper_file_delete
;
249 File
->Read
= ventoy_wrapper_file_read
;
250 File
->Write
= ventoy_wrapper_file_write
;
251 File
->GetPosition
= ventoy_wrapper_file_get_pos
;
252 File
->SetPosition
= ventoy_wrapper_file_set_pos
;
253 File
->GetInfo
= ventoy_wrapper_file_get_info
;
254 File
->SetInfo
= ventoy_wrapper_file_set_info
;
255 File
->Flush
= ventoy_wrapper_file_flush
;
256 File
->OpenEx
= ventoy_wrapper_file_open_ex
;
257 File
->ReadEx
= ventoy_wrapper_file_read_ex
;
258 File
->WriteEx
= ventoy_wrapper_file_write_ex
;
259 File
->FlushEx
= ventoy_wrapper_file_flush_ex
;
264 STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
266 IN EFI_HANDLE Handle
,
267 IN EFI_GUID
*Protocol
,
271 EFI_STATUS Status
= EFI_SUCCESS
;
273 debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol
));
274 Status
= g_system_wrapper
.OriHandleProtocol(Handle
, Protocol
, Interface
);
276 if (CompareGuid(Protocol
, &gEfiSimpleFileSystemProtocolGuid
))
278 EFI_FILE_PROTOCOL
*FileProtocol
= NULL
;
279 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*pFile
= *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**)(Interface
));
281 pFile
->OpenVolume(pFile
, &FileProtocol
);
283 debug("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
284 pFile
, pFile
->OpenVolume
, FileProtocol
, FileProtocol
->Open
);
292 STATIC EFI_STATUS EFIAPI ventoy_open_protocol
294 IN EFI_HANDLE Handle
,
295 IN EFI_GUID
*Protocol
,
296 OUT VOID
**Interface
, OPTIONAL
297 IN EFI_HANDLE AgentHandle
,
298 IN EFI_HANDLE ControllerHandle
,
302 debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol
));
303 return g_system_wrapper
.OriOpenProtocol(Handle
, Protocol
, Interface
, AgentHandle
, ControllerHandle
, Attributes
);
306 STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
308 IN EFI_GUID
*Protocol
,
309 IN VOID
*Registration
, OPTIONAL
313 debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol
));
314 return g_system_wrapper
.OriLocateProtocol(Protocol
, Registration
, Interface
);
317 EFI_STATUS EFIAPI
ventoy_wrapper_system(VOID
)
319 ventoy_wrapper(gBS
, g_system_wrapper
, LocateProtocol
, ventoy_locate_protocol
);
320 ventoy_wrapper(gBS
, g_system_wrapper
, HandleProtocol
, ventoy_handle_protocol
);
321 ventoy_wrapper(gBS
, g_system_wrapper
, OpenProtocol
, ventoy_open_protocol
);