0

我下载了 BIOS rom 并使用 UEFITool 获取文件列表: ROM Structure

所以我知道所有存在的文件的“名称”。然后我尝试使用“GetSectionFromAnyFv”获取文件,但无法获取所有文件,只能获取红色箭头下卷中的文件。例如紫色箭头下的音量也有文件,但我无法得到它。

LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer) 只返回 1 个句柄 [NumberOfHandles = 1],但我可以看到有超过 1 个卷。

如果我尝试使用 for(for NumberOfHandles) 获取文件并遍历所有获取 guid 的文件,则相同。只是无法获取所有文件。

可能是什么问题呢?PS:每个 FV2 HOB 的 ProcessFirmwareVolume 返回 20,这意味着“固件卷块协议”已经被处理。

#include "FileByGuid.h"

EFI_GUID TextToGuid(CHAR16* stGUID)
{
    EFI_GUID NameGuid;

    stGUID[8] = '\0';
    stGUID[13] = '\0';
    stGUID[18] = '\0';
    NameGuid.Data1 = (UINT32)StrHexToUintn(&stGUID[0]);
    NameGuid.Data2 = (UINT16)StrHexToUintn(&stGUID[9]);
    NameGuid.Data3 = (UINT16)StrHexToUintn(&stGUID[14]);

    for (int i = 23; i < 37; i++)
    {
        Print(L"");
        stGUID[i] = stGUID[i + 1];
    }

    UINTN D4 = StrHexToUintn(&stGUID[19]);
    for (int i = 7; i >= 0; i--)
    {
        NameGuid.Data4[i] = (UINT8)(D4 & 0xFF);
        D4 = D4 >> 8;
    }
    return NameGuid;
}

EFI_STATUS
EFIAPI
FileByGuidDriverEntryPoint(
    IN EFI_HANDLE        ImageHandle,
    IN EFI_SYSTEM_TABLE* SystemTable
)
{
    EFI_FIRMWARE_VOLUME2_PROTOCOL* fv;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* fs;
    EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL* fvb;
    EFI_DEVICE_PATH_PROTOCOL* dp;
    EFI_BLOCK_IO2_PROTOCOL* bio;
    EFI_BLOCK_IO_PROTOCOL* bio2;

    EFI_FILE_PROTOCOL       *OpenedFileHandle;
    EFI_FILE_HANDLE         Root;
    EFI_STATUS              Status, GetSectionStatus;
    UINTN                   index;
    EFI_HANDLE              *sfsHandleBuffer = NULL;
    EFI_HANDLE              *fvHandleBuffer = NULL;
    EFI_HANDLE              *fvbHandleBuffer = NULL;
    EFI_HANDLE* bioHandleBuffer = NULL;
    EFI_HANDLE* bio2HandleBuffer = NULL;
    EFI_HANDLE              FvProtocolHandle;
    UINTN                   sfsHandleCount = 0;
    UINTN                   fvHandleCount = 0;
    UINTN                   fvbHandleCount = 0;
    UINTN                   bioHandleCount = 0;
    UINTN                   bio2HandleCount = 0;
    UINTN                   Size;
    EFI_FV_FILETYPE         FileType;
    UINTN                   counter = 0;
    VOID                    *Buffer;
    VOID                    *Key;
    EFI_GUID                fvNameGuid;
    EFI_GUID                NameGuid;
    CHAR16* stGUID = L"114CA60C-D965-4C13-BEF7-C4062248E1FA";
//  UINTN                   EventIndex;
//  EFI_INPUT_KEY               Keys;
    EFI_FV_FILE_ATTRIBUTES  Attributes;
    EFI_FIRMWARE_VOLUME_HEADER  *FirmwareVolumeHeader;
    EFI_PEI_HOB_POINTERS    Hob;
//  BOOLEAN MediaPresent;
//  PARTITION_DETECT_ROUTINE* Routine;
//  BOOLEAN MediaPresent;
//  EFI_DISK_IO_PROTOCOL* DiskIo;
//  EFI_DISK_IO2_PROTOCOL* DiskIo2;

    gBS->SetWatchdogTimer(0, 0, 0, NULL);
    gST = SystemTable;


    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolumeBlock2ProtocolGuid, NULL, &fvbHandleCount, &fvbHandleBuffer);
    AsciiPrint("\r\nfv2_block_HandleCount: %d\r\n", fvbHandleCount);
    for (index = 0; index < (int)fvbHandleCount; index++)
    {
        //Status = gBS->OpenProtocol(fvbHandleBuffer[index], &gEfiFirmwareVolumeBlock2ProtocolGuid, (VOID**)&fvb, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
        Status = gBS->HandleProtocol(fvbHandleBuffer[index], &gEfiFirmwareVolume2ProtocolGuid, &fvb);
        AsciiPrint("-HP fv_block fv2 Status: %d; DevicePath: %s\r\n", Status, ConvertDevicePathToText(DevicePathFromHandle(fvbHandleBuffer[index]), TRUE, TRUE));
    }

    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
    AsciiPrint("\r\nsfsHandleCount: %d\r\n", sfsHandleCount);
    for (index = 0; index < (int)sfsHandleCount; index++)
        AsciiPrint("-sfs[%d] handle: %d; device path: %s\r\n", index, sfsHandleBuffer[index], ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));
    
    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
    AsciiPrint("\r\nDevicePathHandleCount: %d\r\n", sfsHandleCount);
    //for (index = 0; index < (int)sfsHandleCount; index++)
    //  AsciiPrint("dp[%d] device path: %s\r\n", index, ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));

    AsciiPrint("\r\nHOB:\r\n");
    for (Hob.Raw = GetHobList(); !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) 
    {
        if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV2   || GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV3)
        {
            FvProtocolHandle = NULL;

            FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)(Hob.FirmwareVolume->BaseAddress);
            Status = gDS->ProcessFirmwareVolume(FirmwareVolumeHeader, Hob.FirmwareVolume2->Length, &FvProtocolHandle);

            if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV3)
                AsciiPrint("-FV3: Status: %d; FvProtocolHandle: %d; Extracted?:%d; AuthenStatus:%d;\r\n GUID:%g\r\n", Status, FvProtocolHandle, Hob.FirmwareVolume3->ExtractedFv, Hob.FirmwareVolume3->AuthenticationStatus, Hob.FirmwareVolume3->FvName);
            else if (GET_HOB_TYPE(Hob) == EFI_HOB_TYPE_FV2)
                AsciiPrint("-FV2: Status: %d; FvProtocolHandle: %d; FileName: %g; \r\n GUID:%g\r\n", Status, FvProtocolHandle, Hob.FirmwareVolume2->FileName, Hob.FirmwareVolume2->FvName);
            else
                AsciiPrint("-FV:  Status: %d; FvProtocolHandle: %d\r\n", Status, FvProtocolHandle);
        }
    }
    AsciiPrint("End HOB\r\n");

    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &fvHandleCount, &fvHandleBuffer);
    AsciiPrint("\r\nfv2HandleCount: %d\r\n", fvHandleCount);
    for (index = 0; index < (int) fvHandleCount; index++)
    {
        Status = gBS->HandleProtocol(fvHandleBuffer[index], &gEfiFirmwareVolume2ProtocolGuid, (VOID**) &fv);
        AsciiPrint("-index: %d; HPfvStatus: %d; DevicePath: %s\r\n", index, Status, ConvertDevicePathToText(DevicePathFromHandle(fvbHandleBuffer[index]), TRUE, TRUE));
        if (EFI_ERROR(Status))
            continue;

        FileType = EFI_FV_FILETYPE_ALL;
        Key = AllocatePool(fv->KeySize);
        ZeroMem(Key, fv->KeySize);

        Status = fv->GetNextFile(fv, Key, &FileType, &fvNameGuid, &Attributes, &Size);
        while (Status!= EFI_NOT_FOUND)
        {
            FileType = EFI_FV_FILETYPE_ALL;
            counter++;
            //if (counter % 15 == 0)
            //  AsciiPrint("Status: %d;  __file_GUID:%g\r\n", Status, fvNameGuid);
            Status = fv->GetNextFile(fv, Key, &FileType, &fvNameGuid, &Attributes, &Size);
        }

        AsciiPrint("sectionFilesCount: %d\r\n", counter);
        counter = 0;
        FreePool(Key);
    }
    
    NameGuid = TextToGuid(stGUID);
    //AsciiPrint("\r\n%g\r\n", NameGuid);

    GetSectionStatus = GetSectionFromAnyFv(&NameGuid, EFI_SECTION_ALL, 0, (VOID**)&Buffer, &Size);
    AsciiPrint("GetSectionFromAnyFvStatus = %d\r\n", Status);



    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &bioHandleCount, &bioHandleBuffer);
    AsciiPrint("\r\nbioHandleCount: %d\r\n", bioHandleCount);
    for (index = 0; index < (int)bioHandleCount; index++)
    {
        Status = gBS->HandleProtocol(bioHandleBuffer[index], &gEfiBlockIoProtocolGuid, &bio);

        dp = DevicePathFromHandle(bioHandleBuffer[index]);
        while (!IsDevicePathEnd(NextDevicePathNode(dp)))
            dp = NextDevicePathNode(dp);

        AsciiPrint("-HP BlockIO Status: %d; handle: %d; DevicePath: %s\r\n", Status, bioHandleBuffer[index], ConvertDevicePathToText(dp, TRUE, TRUE));
        AsciiPrint("--MediaPresent: %d; RemovableMedia: %d; LogicalPartition: %d\r\n", bio->Media->MediaPresent, bio->Media->RemovableMedia, bio->Media->LogicalPartition);
    }

    Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIo2ProtocolGuid, NULL, &bio2HandleCount, &bio2HandleBuffer);
    AsciiPrint("\r\nbio2HandleCount: %d\r\n", bio2HandleCount);
    for (index = 0; index < (int)bio2HandleCount; index++)
    {
        Status = gBS->HandleProtocol(bio2HandleBuffer[index], &gEfiBlockIo2ProtocolGuid, &bio2);

        dp = DevicePathFromHandle(bio2HandleBuffer[index]);
        while (!IsDevicePathEnd(NextDevicePathNode(dp)))
            dp = NextDevicePathNode(dp);

        AsciiPrint("-HP BlockIO2 Status: %d; handle: %d; DevicePath: %s\r\n", Status, bio2HandleBuffer[index], ConvertDevicePathToText(dp, TRUE, TRUE));
        AsciiPrint("--MediaPresent: %d; RemovableMedia: %d; LogicalPartition: %d\r\n", bio2->Media->MediaPresent, bio2->Media->RemovableMedia, bio2->Media->LogicalPartition);
    }


    AsciiPrint("\r\n");
    //save
    if (!EFI_ERROR(GetSectionStatus))
    {
        Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &sfsHandleCount, &sfsHandleBuffer);
        for (index = 0; index < (int)sfsHandleCount; index++)
        {
            fs = NULL;
            OpenedFileHandle = NULL;
            Root = NULL;

            Status = gBS->HandleProtocol(sfsHandleBuffer[index], &gEfiSimpleFileSystemProtocolGuid, (VOID**)&fs);
            if (EFI_ERROR(Status))
                continue;

            Status = fs->OpenVolume(fs, &Root);
            Status = Root->Open(Root, &OpenedFileHandle, L"EFI\\Boot", EFI_FILE_MODE_READ, 0);
            if (EFI_ERROR(Status))
                continue;

            Status = Root->Open(Root, &OpenedFileHandle, L"file", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);

            if (!EFI_ERROR(Status)) //уже существует
                Root->Delete(OpenedFileHandle);

            Status = Root->Open(Root, &OpenedFileHandle, L"file", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);

            if (!EFI_ERROR(Status))
            {
                Status = Root->Write(OpenedFileHandle, &Size, Buffer);
                AsciiPrint("WriteSt:%d; DevicePath:%s\r\n", Status, ConvertDevicePathToText(DevicePathFromHandle(sfsHandleBuffer[index]), TRUE, TRUE));
            }
            Status = Root->Close(OpenedFileHandle);
        }
    }

    if (Buffer != NULL)
        FreePool(Buffer);

    return EFI_SUCCESS;
}

  1. 获取所有支持 FV2 协议的句柄;
  2. 处理所有 HOB,因此支持 FV2 协议的句柄数量可能会增加;
  3. 对于 FV2 协议,我获取句柄数,然后获取卷名(支持 FV2 协议的句柄的设备路径)和文件数:在这里我可以看到并非所有卷都已处理;
  4. GetSectionFromAnyFv(*) 然后不使用简单文件系统协议的部分和最后保存文件。
4

0 回答 0