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 #define PROCOTOL_SLEEP_MSECONDS 0
42 #define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS)
44 STATIC ventoy_system_wrapper g_system_wrapper
;
46 static struct well_known_guid g_efi_well_known_guids
[] =
48 { &gEfiAbsolutePointerProtocolGuid
, "AbsolutePointer" },
49 { &gEfiAcpiTableProtocolGuid
, "AcpiTable" },
50 { &gEfiBlockIoProtocolGuid
, "BlockIo" },
51 { &gEfiBlockIo2ProtocolGuid
, "BlockIo2" },
52 { &gEfiBusSpecificDriverOverrideProtocolGuid
, "BusSpecificDriverOverride" },
53 { &gEfiComponentNameProtocolGuid
, "ComponentName" },
54 { &gEfiComponentName2ProtocolGuid
, "ComponentName2" },
55 { &gEfiDevicePathProtocolGuid
, "DevicePath" },
56 { &gEfiDriverBindingProtocolGuid
, "DriverBinding" },
57 { &gEfiDiskIoProtocolGuid
, "DiskIo" },
58 { &gEfiDiskIo2ProtocolGuid
, "DiskIo2" },
59 { &gEfiGraphicsOutputProtocolGuid
, "GraphicsOutput" },
60 { &gEfiHiiConfigAccessProtocolGuid
, "HiiConfigAccess" },
61 { &gEfiHiiFontProtocolGuid
, "HiiFont" },
62 { &gEfiLoadFileProtocolGuid
, "LoadFile" },
63 { &gEfiLoadFile2ProtocolGuid
, "LoadFile2" },
64 { &gEfiLoadedImageProtocolGuid
, "LoadedImage" },
65 { &gEfiLoadedImageDevicePathProtocolGuid
, "LoadedImageDevicePath"},
66 { &gEfiPciIoProtocolGuid
, "PciIo" },
67 { &gEfiSerialIoProtocolGuid
, "SerialIo" },
68 { &gEfiSimpleFileSystemProtocolGuid
, "SimpleFileSystem" },
69 { &gEfiSimpleTextInProtocolGuid
, "SimpleTextInput" },
70 { &gEfiSimpleTextInputExProtocolGuid
, "SimpleTextInputEx" },
71 { &gEfiSimpleTextOutProtocolGuid
, "SimpleTextOutput" },
74 STATIC CHAR8 gEfiGuidName
[128];
76 static const char * ventoy_get_guid_name(EFI_GUID
*guid
)
80 for (i
= 0; i
< ARRAY_SIZE(g_efi_well_known_guids
); i
++)
82 if (CompareGuid(g_efi_well_known_guids
[i
].guid
, guid
))
84 return g_efi_well_known_guids
[i
].name
;
88 AsciiSPrint(gEfiGuidName
, sizeof(gEfiGuidName
), "%g", guid
);
92 STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
95 IN EFI_GUID
*Protocol
,
99 EFI_STATUS Status
= EFI_SUCCESS
;
101 debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
102 Status
= g_system_wrapper
.OriHandleProtocol(Handle
, Protocol
, Interface
);
104 if (CompareGuid(Protocol
, &gEfiSimpleFileSystemProtocolGuid
))
106 EFI_FILE_PROTOCOL
*FileProtocol
= NULL
;
107 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*pFile
= *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**)(Interface
));
109 pFile
->OpenVolume(pFile
, &FileProtocol
);
111 trace("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
112 pFile
, pFile
->OpenVolume
, FileProtocol
, FileProtocol
->Open
);
120 STATIC EFI_STATUS EFIAPI ventoy_open_protocol
122 IN EFI_HANDLE Handle
,
123 IN EFI_GUID
*Protocol
,
124 OUT VOID
**Interface
, OPTIONAL
125 IN EFI_HANDLE AgentHandle
,
126 IN EFI_HANDLE ControllerHandle
,
130 debug("ventoy_open_protocol:<%p> %a", Handle
, ventoy_get_guid_name(Protocol
)); debug_sleep();
131 return g_system_wrapper
.OriOpenProtocol(Handle
, Protocol
, Interface
, AgentHandle
, ControllerHandle
, Attributes
);
134 STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
136 IN EFI_GUID
*Protocol
,
137 IN VOID
*Registration
, OPTIONAL
141 debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
142 return g_system_wrapper
.OriLocateProtocol(Protocol
, Registration
, Interface
);
145 STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer
147 IN EFI_LOCATE_SEARCH_TYPE SearchType
,
148 IN EFI_GUID
*Protocol
, OPTIONAL
149 IN VOID
*SearchKey
, OPTIONAL
150 IN OUT UINTN
*NoHandles
,
151 OUT EFI_HANDLE
**Buffer
154 debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
155 return g_system_wrapper
.OriLocateHandleBuffer(SearchType
, Protocol
, SearchKey
, NoHandles
, Buffer
);
158 STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle
160 IN EFI_HANDLE Handle
,
161 OUT EFI_GUID
***ProtocolBuffer
,
162 OUT UINTN
*ProtocolBufferCount
165 debug("ventoy_protocol_per_handle:%p", Handle
); debug_sleep();
166 return g_system_wrapper
.OriProtocolsPerHandle(Handle
, ProtocolBuffer
, ProtocolBufferCount
);
169 EFI_STATUS EFIAPI ventoy_locate_handle
171 IN EFI_LOCATE_SEARCH_TYPE SearchType
,
172 IN EFI_GUID
*Protocol
, OPTIONAL
173 IN VOID
*SearchKey
, OPTIONAL
174 IN OUT UINTN
*BufferSize
,
175 OUT EFI_HANDLE
*Buffer
180 EFI_STATUS Status
= EFI_SUCCESS
;
182 debug("ventoy_locate_handle: %d %a %p", SearchType
, ventoy_get_guid_name(Protocol
), SearchKey
);
183 Status
= g_system_wrapper
.OriLocateHandle(SearchType
, Protocol
, SearchKey
, BufferSize
, Buffer
);
184 debug("ventoy_locate_handle: %r Handle Count:%u", Status
, *BufferSize
/sizeof(EFI_HANDLE
));
186 if (EFI_SUCCESS
== Status
)
188 for (i
= 0; i
< *BufferSize
/ sizeof(EFI_HANDLE
); i
++)
190 if (Buffer
[i
] == gBlockData
.Handle
)
193 Buffer
[0] = Buffer
[i
];
195 debug("####### Handle at %u", i
);
206 STATIC EFI_STATUS EFIAPI ventoy_locate_device_path
208 IN EFI_GUID
*Protocol
,
209 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
,
210 OUT EFI_HANDLE
*Device
213 debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
214 return g_system_wrapper
.OriLocateDevicePath(Protocol
, DevicePath
, Device
);
217 EFI_STATUS EFIAPI
ventoy_wrapper_system(VOID
)
219 ventoy_wrapper(gBS
, g_system_wrapper
, LocateProtocol
, ventoy_locate_protocol
);
220 ventoy_wrapper(gBS
, g_system_wrapper
, HandleProtocol
, ventoy_handle_protocol
);
221 ventoy_wrapper(gBS
, g_system_wrapper
, OpenProtocol
, ventoy_open_protocol
);
222 ventoy_wrapper(gBS
, g_system_wrapper
, LocateHandleBuffer
, ventoy_locate_handle_buffer
);
223 ventoy_wrapper(gBS
, g_system_wrapper
, ProtocolsPerHandle
, ventoy_protocol_per_handle
);
224 ventoy_wrapper(gBS
, g_system_wrapper
, LocateHandle
, ventoy_locate_handle
);
225 ventoy_wrapper(gBS
, g_system_wrapper
, LocateDevicePath
, ventoy_locate_device_path
);