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 #define PROCOTOL_SLEEP_MSECONDS 0
41 #define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS)
43 STATIC ventoy_system_wrapper g_system_wrapper
;
45 static struct well_known_guid g_efi_well_known_guids
[] =
47 { &gEfiAbsolutePointerProtocolGuid
, "AbsolutePointer" },
48 { &gEfiAcpiTableProtocolGuid
, "AcpiTable" },
49 { &gEfiBlockIoProtocolGuid
, "BlockIo" },
50 { &gEfiBlockIo2ProtocolGuid
, "BlockIo2" },
51 { &gEfiBusSpecificDriverOverrideProtocolGuid
, "BusSpecificDriverOverride" },
52 { &gEfiComponentNameProtocolGuid
, "ComponentName" },
53 { &gEfiComponentName2ProtocolGuid
, "ComponentName2" },
54 { &gEfiDevicePathProtocolGuid
, "DevicePath" },
55 { &gEfiDriverBindingProtocolGuid
, "DriverBinding" },
56 { &gEfiDiskIoProtocolGuid
, "DiskIo" },
57 { &gEfiDiskIo2ProtocolGuid
, "DiskIo2" },
58 { &gEfiGraphicsOutputProtocolGuid
, "GraphicsOutput" },
59 { &gEfiHiiConfigAccessProtocolGuid
, "HiiConfigAccess" },
60 { &gEfiHiiFontProtocolGuid
, "HiiFont" },
61 { &gEfiLoadFileProtocolGuid
, "LoadFile" },
62 { &gEfiLoadFile2ProtocolGuid
, "LoadFile2" },
63 { &gEfiLoadedImageProtocolGuid
, "LoadedImage" },
64 { &gEfiLoadedImageDevicePathProtocolGuid
, "LoadedImageDevicePath"},
65 { &gEfiPciIoProtocolGuid
, "PciIo" },
66 { &gEfiSerialIoProtocolGuid
, "SerialIo" },
67 { &gEfiSimpleFileSystemProtocolGuid
, "SimpleFileSystem" },
68 { &gEfiSimpleTextInProtocolGuid
, "SimpleTextInput" },
69 { &gEfiSimpleTextInputExProtocolGuid
, "SimpleTextInputEx" },
70 { &gEfiSimpleTextOutProtocolGuid
, "SimpleTextOutput" },
73 STATIC CHAR8 gEfiGuidName
[128];
75 static const char * ventoy_get_guid_name(EFI_GUID
*guid
)
79 for (i
= 0; i
< ARRAY_SIZE(g_efi_well_known_guids
); i
++)
81 if (CompareGuid(g_efi_well_known_guids
[i
].guid
, guid
))
83 return g_efi_well_known_guids
[i
].name
;
87 AsciiSPrint(gEfiGuidName
, sizeof(gEfiGuidName
), "%g", guid
);
91 STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
94 IN EFI_GUID
*Protocol
,
98 EFI_STATUS Status
= EFI_SUCCESS
;
100 debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
101 Status
= g_system_wrapper
.OriHandleProtocol(Handle
, Protocol
, Interface
);
103 if (CompareGuid(Protocol
, &gEfiSimpleFileSystemProtocolGuid
))
105 EFI_FILE_PROTOCOL
*FileProtocol
= NULL
;
106 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*pFile
= *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**)(Interface
));
108 pFile
->OpenVolume(pFile
, &FileProtocol
);
110 trace("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
111 pFile
, pFile
->OpenVolume
, FileProtocol
, FileProtocol
->Open
);
119 STATIC EFI_STATUS EFIAPI ventoy_open_protocol
121 IN EFI_HANDLE Handle
,
122 IN EFI_GUID
*Protocol
,
123 OUT VOID
**Interface
, OPTIONAL
124 IN EFI_HANDLE AgentHandle
,
125 IN EFI_HANDLE ControllerHandle
,
129 debug("ventoy_open_protocol:<%p> %a", Handle
, ventoy_get_guid_name(Protocol
)); debug_sleep();
130 return g_system_wrapper
.OriOpenProtocol(Handle
, Protocol
, Interface
, AgentHandle
, ControllerHandle
, Attributes
);
133 STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
135 IN EFI_GUID
*Protocol
,
136 IN VOID
*Registration
, OPTIONAL
140 debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
141 return g_system_wrapper
.OriLocateProtocol(Protocol
, Registration
, Interface
);
144 STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer
146 IN EFI_LOCATE_SEARCH_TYPE SearchType
,
147 IN EFI_GUID
*Protocol
, OPTIONAL
148 IN VOID
*SearchKey
, OPTIONAL
149 IN OUT UINTN
*NoHandles
,
150 OUT EFI_HANDLE
**Buffer
153 debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
154 return g_system_wrapper
.OriLocateHandleBuffer(SearchType
, Protocol
, SearchKey
, NoHandles
, Buffer
);
157 STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle
159 IN EFI_HANDLE Handle
,
160 OUT EFI_GUID
***ProtocolBuffer
,
161 OUT UINTN
*ProtocolBufferCount
164 debug("ventoy_protocol_per_handle:%p", Handle
); debug_sleep();
165 return g_system_wrapper
.OriProtocolsPerHandle(Handle
, ProtocolBuffer
, ProtocolBufferCount
);
168 EFI_STATUS EFIAPI ventoy_locate_handle
170 IN EFI_LOCATE_SEARCH_TYPE SearchType
,
171 IN EFI_GUID
*Protocol
, OPTIONAL
172 IN VOID
*SearchKey
, OPTIONAL
173 IN OUT UINTN
*BufferSize
,
174 OUT EFI_HANDLE
*Buffer
179 EFI_STATUS Status
= EFI_SUCCESS
;
181 debug("ventoy_locate_handle: %d %a %p", SearchType
, ventoy_get_guid_name(Protocol
), SearchKey
);
182 Status
= g_system_wrapper
.OriLocateHandle(SearchType
, Protocol
, SearchKey
, BufferSize
, Buffer
);
183 debug("ventoy_locate_handle: %r Handle Count:%u", Status
, *BufferSize
/sizeof(EFI_HANDLE
));
185 if (EFI_SUCCESS
== Status
)
187 for (i
= 0; i
< *BufferSize
/ sizeof(EFI_HANDLE
); i
++)
189 if (Buffer
[i
] == gBlockData
.Handle
)
192 Buffer
[0] = Buffer
[i
];
194 debug("####### Handle at %u", i
);
205 STATIC EFI_STATUS EFIAPI ventoy_locate_device_path
207 IN EFI_GUID
*Protocol
,
208 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
,
209 OUT EFI_HANDLE
*Device
212 debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol
)); debug_sleep();
213 return g_system_wrapper
.OriLocateDevicePath(Protocol
, DevicePath
, Device
);
216 EFI_STATUS EFIAPI
ventoy_wrapper_system(VOID
)
218 ventoy_wrapper(gBS
, g_system_wrapper
, LocateProtocol
, ventoy_locate_protocol
);
219 ventoy_wrapper(gBS
, g_system_wrapper
, HandleProtocol
, ventoy_handle_protocol
);
220 ventoy_wrapper(gBS
, g_system_wrapper
, OpenProtocol
, ventoy_open_protocol
);
221 ventoy_wrapper(gBS
, g_system_wrapper
, LocateHandleBuffer
, ventoy_locate_handle_buffer
);
222 ventoy_wrapper(gBS
, g_system_wrapper
, ProtocolsPerHandle
, ventoy_protocol_per_handle
);
223 ventoy_wrapper(gBS
, g_system_wrapper
, LocateHandle
, ventoy_locate_handle
);
224 ventoy_wrapper(gBS
, g_system_wrapper
, LocateDevicePath
, ventoy_locate_device_path
);