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;
}
- Getting all handles that support FV2 protocol;
- Processing all HOBs so number of handles that support FV2 protocol may increase;
- 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;
- GetSectionFromAnyFv(*) then not interresting part and last saving file using simple file system protocol.