0

I donwloaded BIOS rom and get list of files using UEFITool: ROM Structure

So i know "names" of all files that exist. Then i tried to get file using "GetSectionFromAnyFv" but can't get all files, just files in volume under red arrow. For example volume under violet arrow also have files, but i can't get it.

LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NumberOfHandles, &HandleBuffer) return only 1 handle [NumberOfHandles = 1], but as i can see there are more than 1 volume.

Same if i try get file using for(for NumberOfHandles) and iterate over all files getting guids. Just can't get all files.

What could be the problem? P.S.: ProcessFirmwareVolume for every FV2 HOBs return 20 so that means that "firmware volume block protocol" is alredy processed.

#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. Getting all handles that support FV2 protocol;
  2. Processing all HOBs so number of handles that support FV2 protocol may increase;
  3. For FV2 protocol i get count of handles and then get Volume names (device path for handle that support FV2 protocol) and files count: Here i can see that not all volumes are processd;
  4. GetSectionFromAnyFv(*) then not interresting part and last saving file using simple file system protocol.
away228
  • 31
  • 4

0 Answers0