+
+STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle)
+{
+ UINTN i = 0;
+ UINTN Count = 0;
+ EFI_HANDLE Parent = NULL;
+ EFI_HANDLE *Handles = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL;
+
+ Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid,
+ NULL, &Count, &Handles);
+ if (EFI_ERROR(Status))
+ {
+ return Status;
+ }
+
+ debug("ventoy_find_iso_disk_fs fs count:%u", Count);
+
+ for (i = 0; i < Count; i++)
+ {
+ Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile);
+ if (EFI_ERROR(Status))
+ {
+ continue;
+ }
+
+ 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));
+ Parent = ventoy_get_parent_handle(pDevPath);
+
+ if (Parent == gBlockData.RawBlockIoHandle)
+ {
+ debug("Find ventoy disk fs");
+ gBlockData.DiskFsHandle = Handles[i];
+ gBlockData.pDiskFs = pFile;
+ gBlockData.pDiskFsDevPath = pDevPath;
+ break;
+ }
+ }
+
+ FreePool(Handles);
+
+ return EFI_SUCCESS;
+}
+
+STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle)
+{
+ EFI_HANDLE Image = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ CHAR16 LogVar[4] = L"5";
+
+ if (gIsoUdf)
+ {
+ Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
+ gUdfEfiDriverPath,
+ sizeof(gUdfEfiDriverPath),
+ &Image);
+ debug("load iso UDF efi driver status:%r", Status);
+ }
+ else
+ {
+ Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath,
+ gIso9660EfiDriverPath,
+ sizeof(gIso9660EfiDriverPath),
+ &Image);
+ debug("load iso 9660 efi driver status:%r", Status);
+ }
+
+ if (gDebugPrint)
+ {
+ gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(LogVar), LogVar);
+ }
+
+ gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(LogVar), LogVar);
+
+ gBlockData.IsoDriverImage = Image;
+ Status = gBS->StartImage(Image, NULL, NULL);
+ debug("Start iso efi driver status:%r", Status);
+
+ return EFI_SUCCESS;
+}
+
+STATIC EFI_STATUS ventoy_proc_img_replace_name(ventoy_grub_param_file_replace *replace)
+{
+ UINT32 i;
+ char tmp[256];
+
+ if (replace->magic != GRUB_IMG_REPLACE_MAGIC)
+ {
+ return EFI_SUCCESS;
+ }
+
+ if (replace->old_file_name[0][0] == 0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ AsciiStrCpyS(tmp, sizeof(tmp), replace->old_file_name[0]);
+
+ for (i = 0; i < 256 && tmp[i]; i++)
+ {
+ if (tmp[i] == '/')
+ {
+ tmp[i] = '\\';
+ }
+ }
+
+ AsciiStrCpyS(replace->old_file_name[0], 256, tmp);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI ventoy_get_variable_wrapper
+(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes, OPTIONAL
+ IN OUT UINTN *DataSize,
+ OUT VOID *Data OPTIONAL
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data);
+ if (StrCmp(VariableName, L"SecureBoot") == 0)
+ {
+ if ((*DataSize == 1) && Data)
+ {
+ *(UINT8 *)Data = 0;
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS EFIAPI ventoy_exit_boot_service_wrapper
+(
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+)
+{
+ if (g_org_get_variable)
+ {
+ gRT->GetVariable = g_org_get_variable;
+ g_org_get_variable = NULL;
+ }
+
+ return g_org_exit_boot_service(ImageHandle, MapKey);
+}
+
+STATIC EFI_STATUS EFIAPI ventoy_disable_secure_boot(IN EFI_HANDLE ImageHandle)
+{
+ UINT8 Value = 0;
+ UINTN DataSize = 1;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = gRT->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &DataSize, &Value);
+ if (!EFI_ERROR(Status))
+ {
+ if (DataSize == 1 && Value == 0)
+ {
+ debug("Current secure boot is off, no need to disable");
+ return EFI_SUCCESS;
+ }
+ }
+
+ debug("ventoy_disable_secure_boot");
+
+ /* step1: wrapper security protocol. */
+ /* Do we still need it since we have been loaded ? */
+
+
+ /* step2: fake SecureBoot variable */
+ g_org_exit_boot_service = gBS->ExitBootServices;
+ gBS->ExitBootServices = ventoy_exit_boot_service_wrapper;
+
+ g_org_get_variable = gRT->GetVariable;
+ gRT->GetVariable = ventoy_get_variable_wrapper;
+
+ return EFI_SUCCESS;
+}
+
+