From 89c083d6ad8f0af49af5268aed7c46f5a7ab7801 Mon Sep 17 00:00:00 2001 From: Konstantin Aladyshev Date: Fri, 29 Jul 2022 11:45:50 +0300 Subject: Add lesson about EFI_FIRMWARE_VOLUME2_PROTOCOL Signed-off-by: Konstantin Aladyshev --- UefiLessonsPkg/FfsFile/FfsFile.c | 358 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 UefiLessonsPkg/FfsFile/FfsFile.c (limited to 'UefiLessonsPkg/FfsFile/FfsFile.c') diff --git a/UefiLessonsPkg/FfsFile/FfsFile.c b/UefiLessonsPkg/FfsFile/FfsFile.c new file mode 100644 index 0000000..0ae988f --- /dev/null +++ b/UefiLessonsPkg/FfsFile/FfsFile.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include + + +VOID PrintBuffer(UINT8* Buffer, UINTN BufferSize) +{ + UINTN i=0; + while (i0; j--) { + if ((Buffer[i-j]>0x20) && (Buffer[i-j]<0x7E)) { + Print(L"%c", Buffer[i-j]); + } else { + Print(L"."); + } + } + Print(L"|\n"); + } + } + if (i%16) { + while (i%16) { + Print(L" "); + i++; + } + Print(L" |"); + for (UINT8 j=16; j>0; j--) { + if ((i-j) < BufferSize) { + if ((Buffer[i-j]>0x20) && (Buffer[i-j]<0x7E)) { + Print(L"%c", Buffer[i-j]); + } else { + Print(L"."); + } + } + } + Print(L"|\n"); + } + Print(L"\n"); +} + + +CHAR16* SectionTypeString(EFI_SECTION_TYPE SectionType) +{ + if (SectionType == EFI_SECTION_ALL) + return L"ALL"; + else if (SectionType == EFI_SECTION_COMPRESSION) + return L"COMPRESSION"; + else if (SectionType == EFI_SECTION_GUID_DEFINED) + return L"GUID_DEFINED"; + else if (SectionType == EFI_SECTION_DISPOSABLE) + return L"DISPOSABLE"; + else if (SectionType == EFI_SECTION_PE32) + return L"PE32"; + else if (SectionType == EFI_SECTION_PIC) + return L"PIC"; + else if (SectionType == EFI_SECTION_TE) + return L"TE"; + else if (SectionType == EFI_SECTION_DXE_DEPEX) + return L"DXE_DEPEX"; + else if (SectionType == EFI_SECTION_VERSION) + return L"VERSION"; + else if (SectionType == EFI_SECTION_USER_INTERFACE) + return L"USER_INTERFACE"; + else if (SectionType == EFI_SECTION_COMPATIBILITY16) + return L"COMPATIBILITY16"; + else if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) + return L"FV_IMAGE"; + else if (SectionType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) + return L"SUBTYPE_GUID"; + else if (SectionType == EFI_SECTION_RAW) + return L"RAW"; + else if (SectionType == EFI_SECTION_PEI_DEPEX) + return L"PEI_DEPEX"; + else if (SectionType == EFI_SECTION_MM_DEPEX) + return L"MM_DEPEX"; + else + return L"UNKNOWN"; +} + + +CHAR16* FileTypeString(EFI_FV_FILETYPE FileType) +{ + if (FileType == EFI_FV_FILETYPE_RAW) + return L"RAW"; + else if (FileType == EFI_FV_FILETYPE_FREEFORM) + return L"FREEFORM"; + else if (FileType == EFI_FV_FILETYPE_SECURITY_CORE) + return L"SEC_CORE"; + else if (FileType == EFI_FV_FILETYPE_PEI_CORE) + return L"PEI_CORE"; + else if (FileType == EFI_FV_FILETYPE_DXE_CORE) + return L"DXE_CORE"; + else if (FileType == EFI_FV_FILETYPE_PEIM) + return L"PEIM"; + else if (FileType == EFI_FV_FILETYPE_DRIVER) + return L"DRIVER"; + else if (FileType == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) + return L"COMBINED_PEIM_DRIVER"; + else if (FileType == EFI_FV_FILETYPE_APPLICATION) + return L"APPLICATION"; + else if (FileType == EFI_FV_FILETYPE_MM) + return L"MM"; + else if (FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) + return L"FV_IMAGE"; + else if (FileType == EFI_FV_FILETYPE_COMBINED_MM_DXE) + return L"COMBINED_MM_DXE"; + else if (FileType == EFI_FV_FILETYPE_MM_CORE) + return L"MM_CORE"; + else if (FileType == EFI_FV_FILETYPE_MM_STANDALONE) + return L"MM_STANDALONE"; + else if (FileType == EFI_FV_FILETYPE_MM_CORE_STANDALONE) + return L"MM_CORE_STANDALONE"; + else if ((FileType >= 0xC0) && (FileType <= 0xDF)) + return L"OEM"; + else if ((FileType >= 0xE0) && (FileType <= 0xEF)) + return L"DEBUG"; + else if (FileType == EFI_FV_FILETYPE_FFS_PAD) + return L"FFS_PAD"; + else if ((FileType >= 0xF0) && (FileType <= 0xFF)) + return L"FFS"; + else + return L"UNKNOWN"; +} + + +EFI_STATUS +PrintFiles( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL* FV2Protocol + ) +{ + EFI_STATUS Status; + EFI_GUID FileGuid; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + EFI_FV_FILETYPE FileType; + UINTN Key = 0; + + do { + FileType = EFI_FV_FILETYPE_ALL; + Status = FV2Protocol->GetNextFile( + FV2Protocol, + (VOID**)&Key, + &FileType, + &FileGuid, + &Attributes, + &Size + ); + if (!EFI_ERROR(Status)) + Print(L"%g - %s - %d bytes\n", FileGuid, FileTypeString(FileType), Size); + } while (Status == EFI_SUCCESS); + + return EFI_SUCCESS; +} + + +EFI_STATUS +ReadFile( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL* FV2Protocol, + IN EFI_GUID* FileGuid + ) +{ + EFI_STATUS Status; + UINT8* Buffer = NULL; + UINTN BufferSize; + EFI_FV_FILETYPE FileType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + Status = FV2Protocol->ReadFile( + FV2Protocol, + FileGuid, + (VOID**)&Buffer, + &BufferSize, + &FileType, + &FileAttributes, + &AuthenticationStatus + ); + if (EFI_ERROR(Status)) { + Print(L"Error! ReadFile returned error: %r\n", Status); + return Status; + } + + Print(L"FileType=%s\n", FileTypeString(FileType)); + Print(L"FileAttributes=0x%08x\n", FileAttributes); + Print(L"AuthenticationStatus=0x%08x\n", AuthenticationStatus); + Print(L"\n"); + + Print(L"Raw Data:\n"); + PrintBuffer(Buffer, BufferSize); + Print(L"-------------------------------------\n"); + if (FileType == EFI_FV_FILETYPE_RAW) + return EFI_SUCCESS; + Print(L"Parsed Data:\n\n"); + UINTN i=0; + while (i < BufferSize) { + EFI_COMMON_SECTION_HEADER* SectionHeader = (EFI_COMMON_SECTION_HEADER*) &Buffer[i]; + UINTN SectionSize = SectionHeader->Size[0] + (SectionHeader->Size[1] << 8) + (SectionHeader->Size[2] << 16); + Print(L"Section %s, size 0x%08x\n", SectionTypeString(SectionHeader->Type), SectionSize); + Print(L"Data:\n"); + PrintBuffer(&Buffer[i] + sizeof(EFI_COMMON_SECTION_HEADER), SectionSize - sizeof(EFI_COMMON_SECTION_HEADER)); + i += SectionSize; + if (i%4) + i += (4-(i%4)); + } + FreePool(Buffer); + return EFI_SUCCESS; +} + + +EFI_STATUS +ReadSection( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL* FV2Protocol, + IN EFI_GUID* FileGuid, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance + ) +{ + EFI_STATUS Status; + UINT8* Buffer = NULL; + UINTN BufferSize; + UINT32 AuthenticationStatus; + Print(L"Section %s %d\n", SectionTypeString(SectionType), SectionInstance); + Status = FV2Protocol->ReadSection( + FV2Protocol, + FileGuid, + SectionType, + SectionInstance, + (VOID**)&Buffer, + &BufferSize, + &AuthenticationStatus + ); + if (!EFI_ERROR(Status)) { + PrintBuffer(Buffer, BufferSize); + } else { + Print(L"Error! ReadSection returned error: %r\n", Status); + } + FreePool(Buffer); + return Status; +} + + +VOID Usage() +{ + Print(L"Usage:\n"); + Print(L" FfsFile [ [ ]]\n"); + Print(L"\n"); + Print(L":\n"); + Print(L"GUID name of the File in FFS\n"); + Print(L"\n"); + Print(L":\n"); + Print(L"ALL|COMPRESS|GUIDED|DISPOSABLE|PE32|PIC|TE|DXE_DEPEX|PEI_DEPEX|MM_DEPEX\n"); + Print(L"VERSION|UI|COMPAT16|FV_IMAGE|SUBTYPE_GUID|RAW\n"); + Print(L"\n"); + Print(L": section instance number in a target file\n"); +} + + +INTN +EFIAPI +ShellAppMain ( + IN UINTN Argc, + IN CHAR16 **Argv + ) +{ + EFI_STATUS Status; + + if ((Argc != 1) && (Argc != 2) && (Argc != 4)) { + Usage(); + return EFI_INVALID_PARAMETER; + } + + EFI_GUID FileGuid; + if (Argc > 1) { + Status = StrToGuid(Argv[1], &FileGuid); + if (Status != RETURN_SUCCESS) { + Print(L"Error! Can't convert argument to GUID\n"); + return EFI_INVALID_PARAMETER; + } + } + + EFI_SECTION_TYPE SectionType; + UINTN SectionInstance; + if (Argc == 4) { + if (!StrCmp(Argv[2], L"ALL")) + SectionType = EFI_SECTION_ALL; + else if (!StrCmp(Argv[2], L"COMPRESS")) + SectionType = EFI_SECTION_COMPRESSION; + else if (!StrCmp(Argv[2], L"GUIDED")) + SectionType = EFI_SECTION_GUID_DEFINED; + else if (!StrCmp(Argv[2], L"DISPOSABLE")) + SectionType = EFI_SECTION_DISPOSABLE; + else if (!StrCmp(Argv[2], L"PE32")) + SectionType = EFI_SECTION_PE32; + else if (!StrCmp(Argv[2], L"PIC")) + SectionType = EFI_SECTION_PIC; + else if (!StrCmp(Argv[2], L"TE")) + SectionType = EFI_SECTION_TE; + else if (!StrCmp(Argv[2], L"DXE_DEPEX")) + SectionType = EFI_SECTION_DXE_DEPEX; + else if (!StrCmp(Argv[2], L"VERSION")) + SectionType = EFI_SECTION_VERSION; + else if (!StrCmp(Argv[2], L"UI")) + SectionType = EFI_SECTION_USER_INTERFACE; + else if (!StrCmp(Argv[2], L"COMPAT16")) + SectionType = EFI_SECTION_COMPATIBILITY16; + else if (!StrCmp(Argv[2], L"FV_IMAGE")) + SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE; + else if (!StrCmp(Argv[2], L"SUBTYPE_GUID")) + SectionType = EFI_SECTION_FREEFORM_SUBTYPE_GUID; + else if (!StrCmp(Argv[2], L"RAW")) + SectionType = EFI_SECTION_RAW; + else if (!StrCmp(Argv[2], L"PEI_DEPEX")) + SectionType = EFI_SECTION_PEI_DEPEX; + else if (!StrCmp(Argv[2], L"MM_DEPEX")) + SectionType = EFI_SECTION_MM_DEPEX; + else { + Print(L"Error! Wrong \n"); + return EFI_INVALID_PARAMETER; + } + + SectionInstance = StrDecimalToUintn(Argv[3]); + } + + + EFI_FIRMWARE_VOLUME2_PROTOCOL* FV2Protocol; + Status = gBS->LocateProtocol( + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + (VOID**)&FV2Protocol + ); + if (EFI_ERROR(Status)) { + Print(L"Error! Can't locate EFI_FIRMWARE_VOLUME2_PROTOCOL: %r\n", Status); + return Status; + } + + if (Argc == 1) + return PrintFiles(FV2Protocol); + + if (Argc == 2) + return ReadFile(FV2Protocol, &FileGuid); + + if (Argc == 4) + return ReadSection(FV2Protocol, &FileGuid, SectionType, SectionInstance); + + return EFI_SUCCESS; +} -- cgit v1.2.3-18-g5258