X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/094ba618487596cdc6b800a4de9c140e658423c5..2991f097fb98cfaf1a0ebd5048fc0e8bc08aa20d:/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c index 1ce835a..c0c1fc3 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -152,7 +152,8 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector ventoy_override_chunk *pOverride = g_override_chunk; EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; - debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign); + debug("read iso sector %lu count %u Buffer:%p Align:%u blk:%u", + Sector, Count, Buffer, pRawBlockIo->Media->IoAlign, pRawBlockIo->Media->BlockSize); ReadStart = Sector * 2048; ReadEnd = (Sector + Count) * 2048; @@ -624,26 +625,74 @@ 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 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; + + 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; } @@ -761,11 +810,6 @@ STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName) * */ - if (StrStr(UpperDrvName, L"ISO9660") || StrStr(UpperDrvName, L"UDF")) - { - return TRUE; - } - if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM")) { return TRUE; @@ -867,7 +911,6 @@ STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID) Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); if (EFI_ERROR(Status)) { - debug(); continue; } @@ -1096,14 +1139,15 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im { gBlockData.Media.BlockSize = 512; gBlockData.Media.LastBlock = ImgSize / 512 - 1; + gBlockData.Media.ReadOnly = FALSE; } else { gBlockData.Media.BlockSize = 2048; gBlockData.Media.LastBlock = ImgSize / 2048 - 1; + gBlockData.Media.ReadOnly = TRUE; } - gBlockData.Media.ReadOnly = TRUE; gBlockData.Media.MediaPresent = 1; gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; @@ -1202,6 +1246,98 @@ ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) return EFI_SUCCESS; } +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex_img0(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} +/* Ex version */ +STATIC EFI_STATUS EFIAPI +ventoy_wrapper_file_flush_ex_img1(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) +{ + (VOID)This; + (VOID)Token; + return EFI_SUCCESS; +} + +#define DEF_WRAP_FUNC(n) \ +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_flush_ex_img#n(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token) \ +{\ + (VOID)This;\ + (VOID)Token;\ + return EFI_SUCCESS;\ +} + +#define ITEM_WRAP_FUNC(n) ventoy_wrapper_file_flush_ex_img#n + +#if (VTOY_MAX_CONF_REPLACE > 2) +DEF_WRAP_FUNC(2); +#endif +#if (VTOY_MAX_CONF_REPLACE > 3) +DEF_WRAP_FUNC(3); +#endif +#if (VTOY_MAX_CONF_REPLACE > 4) +DEF_WRAP_FUNC(4); +#endif +#if (VTOY_MAX_CONF_REPLACE > 5) +DEF_WRAP_FUNC(5); +#endif +#if (VTOY_MAX_CONF_REPLACE > 6) +DEF_WRAP_FUNC(6); +#endif +#if (VTOY_MAX_CONF_REPLACE > 7) +DEF_WRAP_FUNC(7); +#endif +#if (VTOY_MAX_CONF_REPLACE > 8) +#error "VTOY_MAX_CONF_REPLACE overflow" +#endif + +static EFI_FILE_FLUSH_EX g_img_flush_func[VTOY_MAX_CONF_REPLACE] = +{ + ventoy_wrapper_file_flush_ex_img0, + ventoy_wrapper_file_flush_ex_img1, +#if (VTOY_MAX_CONF_REPLACE > 2) + ITEM_WRAP_FUNC(2), +#endif +#if (VTOY_MAX_CONF_REPLACE > 3) + ITEM_WRAP_FUNC(3), +#endif +#if (VTOY_MAX_CONF_REPLACE > 4) + ITEM_WRAP_FUNC(4), +#endif +#if (VTOY_MAX_CONF_REPLACE > 5) + ITEM_WRAP_FUNC(5), +#endif +#if (VTOY_MAX_CONF_REPLACE > 6) + ITEM_WRAP_FUNC(6), +#endif +#if (VTOY_MAX_CONF_REPLACE > 7) + ITEM_WRAP_FUNC(7), +#endif +}; + +STATIC ventoy_efi_file_replace *ventoy_wrapper_get_replace(EFI_FILE_HANDLE This) +{ + UINTN i; + + if (This->FlushEx == ventoy_wrapper_file_flush_ex) + { + return &g_efi_file_replace; + } + + for (i = 0; i < VTOY_MAX_CONF_REPLACE; i++) + { + if (This->FlushEx == g_img_flush_func[i]) + { + return g_img_file_replace + i; + } + } + + return NULL; +} STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) @@ -1227,19 +1363,20 @@ ventoy_wrapper_file_close(EFI_FILE_HANDLE This) return EFI_SUCCESS; } - STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) { - (VOID)This; - - if (Position <= g_efi_file_replace.FileSizeBytes) + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); + + if (Position <= replace->FileSizeBytes) { - g_efi_file_replace.CurPos = Position; + replace->CurPos = Position; } else { - g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes; + replace->CurPos = replace->FileSizeBytes; } return EFI_SUCCESS; @@ -1248,9 +1385,11 @@ ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position) { - (VOID)This; + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); - *Position = g_efi_file_replace.CurPos; + *Position = replace->CurPos; return EFI_SUCCESS; } @@ -1260,6 +1399,9 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data) { EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data; + ventoy_efi_file_replace *replace = NULL; + + replace = ventoy_wrapper_get_replace(This); debug("ventoy_wrapper_file_get_info ... %u", *Len); @@ -1277,8 +1419,8 @@ ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, V ZeroMem(Data, sizeof(EFI_FILE_INFO)); Info->Size = sizeof(EFI_FILE_INFO); - Info->FileSize = g_efi_file_replace.FileSizeBytes; - Info->PhysicalSize = g_efi_file_replace.FileSizeBytes; + Info->FileSize = replace->FileSizeBytes; + Info->PhysicalSize = replace->FileSizeBytes; Info->Attribute = EFI_FILE_READ_ONLY; //Info->FileName = EFI_FILE_READ_ONLY; @@ -1292,23 +1434,24 @@ ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data) { EFI_LBA Lba; UINTN ReadLen = *Len; - - (VOID)This; + ventoy_efi_file_replace *replace = NULL; + replace = ventoy_wrapper_get_replace(This); + debug("ventoy_wrapper_file_read ... %u", *Len); - if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes) + if (replace->CurPos + ReadLen > replace->FileSizeBytes) { - ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos; + ReadLen = replace->FileSizeBytes - replace->CurPos; } - Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart; + Lba = replace->CurPos / 2048 + replace->BlockIoSectorStart; ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data); *Len = ReadLen; - g_efi_file_replace.CurPos += ReadLen; + replace->CurPos += ReadLen; return EFI_SUCCESS; } @@ -1319,7 +1462,7 @@ ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer); } -STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File) +STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File, BOOLEAN Img, UINTN Index) { File->Revision = EFI_FILE_PROTOCOL_REVISION2; File->Open = ventoy_wrapper_fs_open; @@ -1335,11 +1478,47 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File) File->OpenEx = ventoy_wrapper_file_open_ex; File->ReadEx = ventoy_wrapper_file_read_ex; File->WriteEx = ventoy_wrapper_file_write_ex; - File->FlushEx = ventoy_wrapper_file_flush_ex; + + if (Img) + { + File->FlushEx = g_img_flush_func[Index]; + } + else + { + File->FlushEx = ventoy_wrapper_file_flush_ex; + } return EFI_SUCCESS; } +STATIC BOOLEAN EFIAPI ventoy_replace_name_match(CHAR8 *pReplace, CHAR8 *pName) +{ + UINTN Len1, Len2; + + Len1 = AsciiStrLen(pReplace); + Len2 = AsciiStrLen(pName); + + if (Len1 == 0 || Len2 == 0) + { + return FALSE; + } + + if (0 == AsciiStriCmp(pReplace, pName)) + { + return TRUE; + } + + if (Len1 > 2 && Len2 > 2) + { + if ((pReplace[0] != '\\') && (pName[0] == '\\') && (0 == AsciiStriCmp(pReplace, pName + 1))) + { + return TRUE; + } + } + + return FALSE; +} + STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open ( EFI_FILE_HANDLE This, @@ -1354,27 +1533,40 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open UINT64 Sectors = 0; EFI_STATUS Status = EFI_SUCCESS; CHAR8 TmpName[256]; + CHAR8 OldName[256]; ventoy_virt_chunk *virt = NULL; + ventoy_grub_param_file_replace *replace = NULL; debug("## ventoy_wrapper_file_open <%s> ", Name); + if ((Mode & EFI_FILE_MODE_WRITE) > 0 && StrCmp(Name, L"\\loader\\random-seed") == 0) + { + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open return NOT_FOUND for random-seed %lx", Mode); + sleep(3); + } + return EFI_NOT_FOUND; + } + Status = g_original_fopen(This, New, Name, Mode, Attributes); if (EFI_ERROR(Status)) { return Status; } + if (g_file_replace_list && g_file_replace_list->magic == GRUB_FILE_REPLACE_MAGIC && g_file_replace_list->new_file_virtual_id < g_virt_chunk_num) { AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); for (j = 0; j < 4; j++) { - if (0 == AsciiStrCmp(g_file_replace_list[i].old_file_name[j], TmpName)) + if (ventoy_replace_name_match(g_file_replace_list[i].old_file_name[j], TmpName)) { g_original_fclose(*New); *New = &g_efi_file_replace.WrapperHandle; - ventoy_wrapper_file_procotol(*New); + ventoy_wrapper_file_procotol(*New, FALSE, 0); virt = g_virt_chunk + g_file_replace_list->new_file_virtual_id; @@ -1400,6 +1592,52 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open } } + for (i = 0; g_img_replace_list && i < VTOY_MAX_CONF_REPLACE; i++) + { + replace = g_img_replace_list + i; + if (replace->magic != GRUB_IMG_REPLACE_MAGIC || replace->new_file_virtual_id >= g_virt_chunk_num) + { + continue; + } + + AsciiSPrint(TmpName, sizeof(TmpName), "%s", Name); + for (j = 0; j < replace->old_file_cnt; j++) + { + AsciiStrCpyS(OldName, sizeof(OldName), replace->old_file_name[j]); + if ((0 == AsciiStrCmp(OldName, TmpName)) || + (AsciiStrnCmp(OldName, "\\loader\\entries\\", 16) == 0 && + AsciiStrCmp(OldName + 16, TmpName) == 0 + ) + ) + { + g_original_fclose(*New); + *New = &(g_img_file_replace[i].WrapperHandle); + ventoy_wrapper_file_procotol(*New, TRUE, i); + + virt = g_virt_chunk + replace->new_file_virtual_id; + + Sectors = (virt->mem_sector_end - virt->mem_sector_start) + (virt->remap_sector_end - virt->remap_sector_start); + + g_img_file_replace[i].BlockIoSectorStart = virt->mem_sector_start; + g_img_file_replace[i].FileSizeBytes = Sectors * 2048; + + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open2 <%s> BlockStart:%lu Sectors:%lu Bytes:%lu", Name, + g_img_file_replace[i].BlockIoSectorStart, Sectors, Sectors * 2048); + sleep(3); + } + + return Status; + } + } + } + + if (g_img_replace_list && StrCmp(Name, L"\\loader\\entries") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } + return Status; }