mirror of https://github.com/acidanthera/audk.git
201 lines
6.7 KiB
C
201 lines
6.7 KiB
C
/** @file
|
|
Copyright (c) 2022, Mikhail Krichanov. All rights reserved.
|
|
SPDX-License-Identifier: BSD-3-Clause
|
|
**/
|
|
|
|
#include "ImageTool.h"
|
|
|
|
static
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *
|
|
CreateEntry (
|
|
IN UINT8 *HiiSectionHeader,
|
|
IN OUT UINT32 *HiiSectionOffset,
|
|
IN BOOLEAN DataIsDirectory
|
|
)
|
|
{
|
|
EFI_IMAGE_RESOURCE_DIRECTORY *RDir;
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry;
|
|
|
|
assert (HiiSectionHeader != NULL);
|
|
assert (HiiSectionOffset != NULL);
|
|
|
|
RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset);
|
|
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
|
|
RDir->NumberOfNamedEntries = 1;
|
|
|
|
Entry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *)(HiiSectionHeader + *HiiSectionOffset);
|
|
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
|
|
Entry->u1.s.NameIsString = 1;
|
|
|
|
if (DataIsDirectory) {
|
|
Entry->u2.s.DataIsDirectory = 1;
|
|
Entry->u2.s.OffsetToDirectory = *HiiSectionOffset;
|
|
}
|
|
|
|
return Entry;
|
|
}
|
|
|
|
static
|
|
void
|
|
CreateStringEntry (
|
|
IN OUT EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry,
|
|
IN UINT8 *HiiSectionHeader,
|
|
IN OUT UINT32 *HiiSectionOffset,
|
|
IN CHAR16 *String
|
|
)
|
|
{
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr;
|
|
|
|
assert (Entry != NULL);
|
|
assert (HiiSectionHeader != NULL);
|
|
assert (HiiSectionOffset != NULL);
|
|
assert (String != NULL);
|
|
|
|
Entry->u1.s.NameOffset = *HiiSectionOffset;
|
|
RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset);
|
|
RDStr->Length = (UINT16)StrLen (String);
|
|
memcpy (RDStr->String, String, RDStr->Length * sizeof (RDStr->String[0]));
|
|
*HiiSectionOffset += sizeof (*RDStr) + RDStr->Length * sizeof (RDStr->String[0]);
|
|
}
|
|
|
|
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiResourceSectionHeaderSize =
|
|
3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)
|
|
+ sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_STRING) + 3 * sizeof (CHAR16)) + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
|
|
|
|
VOID
|
|
InitializeHiiResouceSectionHeader (
|
|
OUT UINT8 *HiiSectionHeader,
|
|
IN UINT32 HiiDataAddress,
|
|
IN UINT32 HiiDataSize
|
|
)
|
|
{
|
|
UINT32 HiiSectionOffset;
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeRDirEntry;
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameRDirEntry;
|
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry;
|
|
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
|
|
|
|
assert (HiiSectionHeader != NULL);
|
|
|
|
HiiSectionOffset = 0;
|
|
//
|
|
// Create Type, Name, Language entries
|
|
//
|
|
TypeRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, TRUE);
|
|
NameRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, TRUE);
|
|
LangRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, FALSE);
|
|
//
|
|
// Create string entry for Type, Name, Language
|
|
//
|
|
CreateStringEntry (TypeRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"HII");
|
|
CreateStringEntry (NameRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"EFI");
|
|
CreateStringEntry (LangRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"BIN");
|
|
//
|
|
// Create Leaf data
|
|
//
|
|
LangRDirEntry->u2.OffsetToData = HiiSectionOffset;
|
|
ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *)(HiiSectionHeader + HiiSectionOffset);
|
|
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
|
|
ResourceDataEntry->OffsetToData = HiiDataAddress + HiiSectionOffset;
|
|
ResourceDataEntry->Size = HiiDataSize;
|
|
}
|
|
|
|
RETURN_STATUS
|
|
ConstructHii (
|
|
IN const char *FileNames[],
|
|
IN UINT32 NumOfFiles,
|
|
IN GUID *HiiGuid,
|
|
OUT void **Hii,
|
|
OUT UINT32 *HiiSize
|
|
)
|
|
{
|
|
UINT8 *HiiPackageData;
|
|
UINT8 *HiiPackageDataPointer;
|
|
EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader;
|
|
EFI_HII_PACKAGE_HEADER *HiiPackageHeader;
|
|
EFI_IFR_FORM_SET *IfrFormSet;
|
|
EFI_HII_PACKAGE_HEADER EndPackage;
|
|
UINT32 Index;
|
|
void *File;
|
|
UINT32 FileSize;
|
|
UINT8 NumberOfFormPackages;
|
|
|
|
assert (Hii != NULL);
|
|
assert (HiiGuid != NULL);
|
|
assert (FileNames != NULL);
|
|
|
|
NumberOfFormPackages = 0;
|
|
|
|
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
|
|
EndPackage.Type = EFI_HII_PACKAGE_END;
|
|
|
|
HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EndPackage);
|
|
|
|
for (Index = 0; Index < NumOfFiles; ++Index) {
|
|
File = UserReadFile (FileNames[Index], &FileSize);
|
|
if (File == NULL) {
|
|
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
|
|
return RETURN_ABORTED;
|
|
}
|
|
|
|
HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)File;
|
|
if (HiiPackageHeader->Type == EFI_HII_PACKAGE_FORMS) {
|
|
if (HiiPackageHeader->Length != FileSize) {
|
|
fprintf (stderr, "ImageTool: Wrong package size in HII package file %s\n", FileNames[Index]);
|
|
free (File);
|
|
return RETURN_ABORTED;
|
|
}
|
|
|
|
if (IsZeroGuid (HiiGuid)) {
|
|
IfrFormSet = (EFI_IFR_FORM_SET *)(HiiPackageHeader + 1);
|
|
CopyGuid (HiiGuid, &IfrFormSet->Guid);
|
|
}
|
|
|
|
++NumberOfFormPackages;
|
|
}
|
|
|
|
HiiPackageListHeader.PackageLength += FileSize;
|
|
free (File);
|
|
}
|
|
|
|
if (NumberOfFormPackages > 1) {
|
|
fprintf (stderr, "ImageTool: The input HII packages contain more than one HII Form package\n");
|
|
return RETURN_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsZeroGuid (HiiGuid)) {
|
|
fprintf (stderr, "ImageTool: HII package list guid is not specified\n");
|
|
return RETURN_ABORTED;
|
|
}
|
|
|
|
CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid);
|
|
|
|
HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength);
|
|
if (HiiPackageData == NULL) {
|
|
return RETURN_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
memmove (HiiPackageData, &HiiPackageListHeader, sizeof (HiiPackageListHeader));
|
|
|
|
HiiPackageDataPointer = HiiPackageData + sizeof (HiiPackageListHeader);
|
|
for (Index = 0; Index < NumOfFiles; ++Index) {
|
|
File = UserReadFile (FileNames[Index], &FileSize);
|
|
if (File == NULL) {
|
|
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
|
|
return RETURN_ABORTED;
|
|
}
|
|
|
|
memmove (HiiPackageDataPointer, File, FileSize);
|
|
HiiPackageDataPointer += FileSize;
|
|
|
|
free (File);
|
|
}
|
|
|
|
memmove (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));
|
|
|
|
*Hii = HiiPackageData;
|
|
*HiiSize = HiiPackageListHeader.PackageLength;
|
|
|
|
return RETURN_SUCCESS;
|
|
}
|