X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/1c5aeb35dc927d7127d3db535512c89c9d23372e..787d950f28e48b4e8c541d2eaa96380e151e90ad:/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 f9323cb..9c8fc0e 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 @@ -34,6 +34,7 @@ #include #include #include +#include #include UINT8 *g_iso_data_buf = NULL; @@ -73,6 +74,9 @@ STATIC UINT8 g_sector_buf[2048]; STATIC EFI_BLOCK_READ g_sector_2048_read = NULL; STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL; +STATIC UINTN g_DriverBindWrapperCnt = 0; +STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList[MAX_DRIVER_BIND_WRAPPER]; + BOOLEAN ventoy_is_cdrom_dp_exist(VOID) { UINTN i = 0; @@ -483,6 +487,8 @@ EFI_STATUS EFIAPI ventoy_block_io_read_real secNum = VirtSec - Lba; } + debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); + if (secNum > g_sector_flag_num) { cur_flag = AllocatePool(secNum * sizeof(ventoy_sector_flag)); @@ -618,26 +624,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; } @@ -670,11 +724,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST continue; } - Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName); - if (EFI_ERROR(Status) || NULL == DriverName) - { - continue; - } + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); if (StrStr(DriverName, DrvName)) { @@ -712,11 +762,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST continue; } - Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName); - if (EFI_ERROR(Status)) - { - continue; - } + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); if (StrStr(DriverName, DrvName)) { @@ -741,6 +787,223 @@ end: return Status; } + +STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName) +{ + UINTN i; + CHAR16 UpperDrvName[256]; + + StrCpyS(UpperDrvName, 256, DrvName); + + for (i = 0; i < 256 && UpperDrvName[i]; i++) + { + if (UpperDrvName[i] >= 'a' && UpperDrvName[i] <= 'z') + { + UpperDrvName[i] = 'A' + (UpperDrvName[i] - 'a'); + } + } + + /* + * suppress some file system drivers + * 1. rEFInd File System Driver + * + */ + + if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM")) + { + return TRUE; + } + + return FALSE; +} + +STATIC VOID ventoy_add_filesystem_wrapper +( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol, + IN CONST CHAR16 *DriverName +) +{ + UINTN j; + + if (g_DriverBindWrapperCnt >= MAX_DRIVER_BIND_WRAPPER) + { + debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt); + return; + } + + if (!ventoy_filesystem_need_wrapper(DriverName)) + { + return; + } + + for (j = 0; j < g_DriverBindWrapperCnt; j++) + { + if (g_DriverBindWrapperList[j].DriverBinding == DriverBindProtocol) + { + debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName, DriverBindProtocol, j, g_DriverBindWrapperCnt); + break; + } + } + + if (j >= g_DriverBindWrapperCnt) + { + g_DriverBindWrapperList[g_DriverBindWrapperCnt].DriverBinding = DriverBindProtocol; + g_DriverBindWrapperList[g_DriverBindWrapperCnt].pfOldSupport = DriverBindProtocol->Supported; + g_DriverBindWrapperCnt++; + debug("Add driverbinding <%s> %p %lu", DriverName, DriverBindProtocol, g_DriverBindWrapperCnt); + } +} + +STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol = NULL; + + debug("ventoy_find_filesystem_driverbind..."); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 2 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 1 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support +( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL +) +{ + UINTN i; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + EFI_DRIVER_BINDING_SUPPORTED pfOldSupport = NULL; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + if (g_DriverBindWrapperList[i].DriverBinding == This) + { + pfOldSupport = g_DriverBindWrapperList[i].pfOldSupport; + break; + } + } + + debug("ventoy_wrapper_driver_bind_support %lu %p", i, pfOldSupport); + + if (!pfOldSupport) + { + return EFI_UNSUPPORTED; + } + + Status = gBS->HandleProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + goto out; + } + + if (0 == CompareMem(gBlockData.Path, DevicePath, gBlockData.DevicePathCompareLen)) + { + debug("return EFI_UNSUPPORTED for ventoy"); + return EFI_UNSUPPORTED; + } + +out: + return pfOldSupport(This, ControllerHandle, RemainingDevicePath); +} + +EFI_STATUS ventoy_disable_ex_filesystem(VOID) +{ + UINTN i; + + ventoy_find_filesystem_driverbind(); + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = ventoy_wrapper_driver_bind_support; + } + + debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt); + ventoy_debug_pause(); + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_enable_ex_filesystem(VOID) +{ + UINTN i; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = g_DriverBindWrapperList[i].pfOldSupport; + } + g_DriverBindWrapperCnt = 0; + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI ventoy_block_io_read_512 ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -875,14 +1138,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; @@ -1137,6 +1401,16 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open 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)) {