mirror of https://github.com/ventoy/Ventoy.git
Support nested boot.
For example: Ventoy-->rEFInd.iso-->Ventoy-->Windows.iso
This commit is contained in:
parent
094ba61848
commit
7b78fe555e
|
@ -363,11 +363,23 @@ EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath
|
|||
return Handle;
|
||||
}
|
||||
|
||||
STATIC ventoy_ram_disk g_backup_ramdisk_param;
|
||||
STATIC ventoy_os_param g_backup_os_param_var;
|
||||
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID)
|
||||
{
|
||||
UINTN DataSize;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_GUID VarGuid = VENTOY_GUID;
|
||||
|
||||
DataSize = sizeof(g_backup_ramdisk_param);
|
||||
Status = gRT->GetVariable(L"VentoyRamDisk", &VarGuid, NULL, &DataSize, &g_backup_ramdisk_param);
|
||||
if (!EFI_ERROR(Status))
|
||||
{
|
||||
debug("find previous ramdisk variable <%llu>", g_backup_ramdisk_param.DiskSize);
|
||||
}
|
||||
|
||||
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(g_ramdisk_param), &(g_ramdisk_param));
|
||||
|
@ -381,20 +393,37 @@ EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID)
|
|||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_GUID VarGuid = VENTOY_GUID;
|
||||
|
||||
if (g_backup_ramdisk_param.DiskSize > 0 && g_backup_ramdisk_param.PhyAddr > 0)
|
||||
{
|
||||
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(g_backup_ramdisk_param), &g_backup_ramdisk_param);
|
||||
debug("resotre ramdisk variable %r", Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
0, NULL);
|
||||
debug("delete efi variable %r", Status);
|
||||
debug("delete ramdisk variable %r", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_save_variable(VOID)
|
||||
{
|
||||
UINTN DataSize;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_GUID VarGuid = VENTOY_GUID;
|
||||
|
||||
DataSize = sizeof(g_backup_os_param_var);
|
||||
Status = gRT->GetVariable(L"VentoyOsParam", &VarGuid, NULL, &DataSize, &g_backup_os_param_var);
|
||||
if (!EFI_ERROR(Status))
|
||||
{
|
||||
debug("find previous efi variable <%a>", g_backup_os_param_var.vtoy_img_path);
|
||||
}
|
||||
|
||||
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(g_chain->os_param), &(g_chain->os_param));
|
||||
|
@ -408,10 +437,20 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID)
|
|||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_GUID VarGuid = VENTOY_GUID;
|
||||
|
||||
if (0 == CompareMem(&(g_backup_os_param_var.guid), &VarGuid, sizeof(EFI_GUID)))
|
||||
{
|
||||
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(g_backup_os_param_var), &(g_backup_os_param_var));
|
||||
debug("restore efi variable %r", Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
0, NULL);
|
||||
debug("delete efi variable %r", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,6 @@ typedef struct ventoy_virt_chunk
|
|||
{ 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }}
|
||||
|
||||
|
||||
#define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy"
|
||||
|
||||
#if defined (MDE_CPU_IA32)
|
||||
#define VENTOY_UEFI_DESC L"IA32 UEFI"
|
||||
|
|
|
@ -624,26 +624,77 @@ EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This)
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC UINTN ventoy_get_current_device_path_id(VOID)
|
||||
{
|
||||
UINTN i = 0;
|
||||
UINTN Count = 0;
|
||||
UINTN NameLen = 0;
|
||||
UINTN MaxId = 0;
|
||||
UINTN CurId = 0;
|
||||
BOOLEAN Find = FALSE;
|
||||
EFI_HANDLE *Handles = NULL;
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
|
||||
VENDOR_DEVICE_PATH *venPath = NULL;
|
||||
|
||||
NameLen = StrSize(L"ventoy_xxx");
|
||||
|
||||
Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid,
|
||||
NULL, &Count, &Handles);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
|
||||
if (EFI_ERROR(Status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DevicePath->Type == HARDWARE_DEVICE_PATH && DevicePath->SubType == HW_VENDOR_DP)
|
||||
{
|
||||
venPath = (VENDOR_DEVICE_PATH *)DevicePath;
|
||||
if (CompareGuid(&venPath->Guid, &gVtoyBlockDevicePathGuid))
|
||||
{
|
||||
CurId = StrDecimalToUintn((CHAR16 *)(venPath + 1) + StrLen(L"ventoy_"));
|
||||
MaxId = MAX(MaxId, CurId);
|
||||
Find = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreePool(Handles);
|
||||
|
||||
return Find ? (MaxId + 1) : 0;
|
||||
}
|
||||
|
||||
EFI_STATUS EFIAPI ventoy_fill_device_path(VOID)
|
||||
{
|
||||
UINTN CurVtoyDpId = 0;
|
||||
UINTN NameLen = 0;
|
||||
UINT8 TmpBuf[128] = {0};
|
||||
VENDOR_DEVICE_PATH *venPath = NULL;
|
||||
CHAR16 VtoyDpName[32];
|
||||
|
||||
CurVtoyDpId = ventoy_get_current_device_path_id();
|
||||
UnicodeSPrintAsciiFormat(VtoyDpName, sizeof(VtoyDpName), "ventoy_%03lu", CurVtoyDpId);
|
||||
|
||||
venPath = (VENDOR_DEVICE_PATH *)TmpBuf;
|
||||
NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME);
|
||||
NameLen = StrSize(VtoyDpName);
|
||||
venPath->Header.Type = HARDWARE_DEVICE_PATH;
|
||||
venPath->Header.SubType = HW_VENDOR_DP;
|
||||
venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||
venPath->Header.Length[1] = 0;
|
||||
CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID));
|
||||
CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen);
|
||||
CopyMem(venPath + 1, VtoyDpName, NameLen);
|
||||
|
||||
gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf);
|
||||
gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen;
|
||||
|
||||
debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
|
||||
debug("gBlockData.Path=<%lu><%s>\n", CurVtoyDpId, ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue