Fix more builder issues and perform the initial UEFIReplace port

This commit is contained in:
vit9696 2018-09-01 10:29:46 +03:00
parent 2d02eeab6d
commit 0169c8c904
17 changed files with 402 additions and 61 deletions

View file

@ -70,6 +70,7 @@ typedef size_t USTATUS;
#define U_PEI_CORE_ENTRY_POINT_NOT_FOUND 48
#define U_INVALID_STORE_SIZE 49
#define U_UNKNOWN_COMPRESSION_ALGORITHM 50
#define U_NOTHING_TO_PATCH 51
#define U_NOT_IMPLEMENTED 0xFF
// UDK porting definitions

View file

@ -363,6 +363,7 @@ struct CBString : public tagbstring {
// QString compatibility methods
const char *toLocal8Bit() const { return *this; }
bool contains(const char *str) { return find(str) >= 0; }
bool isEmpty() const { return slen == 0; }
void clear() { *this = ""; }
CBString left(int len) const { return midstr(0, len); }

View file

@ -10,6 +10,8 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <cstdio>
#include "ffs.h"
#include "guiddatabase.h"
@ -69,6 +71,32 @@ UString guidToUString(const EFI_GUID & guid, bool convertToString)
guid.Data4[7]);
}
bool ustringToGuid(const UString & str, EFI_GUID & guid)
{
unsigned long p0;
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
int err = std::sscanf(str.toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
if (err == 0)
return false;
guid.Data1 = p0;
guid.Data2 = p1;
guid.Data3 = p2;
guid.Data4[0] = p3;
guid.Data4[1] = p4;
guid.Data4[2] = p5;
guid.Data4[3] = p6;
guid.Data4[4] = p7;
guid.Data4[5] = p8;
guid.Data4[6] = p9;
guid.Data4[7] = p10;
return true;
}
UString fileTypeToUString(const UINT8 type)
{
switch (type)

View file

@ -23,6 +23,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#pragma pack(push,1)
extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
extern bool ustringToGuid(const UString& str, EFI_GUID& guid);
extern UString fileTypeToUString(const UINT8 type);
extern UString sectionTypeToUString(const UINT8 type);

View file

@ -99,7 +99,7 @@ USTATUS FfsBuilder::build(const UModelIndex & index, UByteArray & reconstructed)
return result;
break;
default:
msg(usprintf("build: unknown item type %1").arg(model->type(index)), index);
msg(usprintf("build: unknown item type %d", model->type(index)), index);
return U_UNKNOWN_ITEM_TYPE;
}
@ -978,7 +978,8 @@ USTATUS FfsBuilder::buildNvramStore(const UModelIndex & index, UByteArray & stor
// Recalculate store checksum
UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
// Write new checksum
body.replace((const UINT32)body.size() - sizeof(UINT32), sizeof(UINT32), (const char *)&calculatedCrc, sizeof(UINT32));
UINT32 *crc = reinterpret_cast<UINT32 *>(body.data() + body.size() - sizeof(UINT32));
std::memcpy(crc, &calculatedCrc, sizeof(UINT32));
}
else if(type == Types::EvsaStore) {
UByteArray store = header + body;
@ -1048,7 +1049,7 @@ USTATUS FfsBuilder::buildPadFile(const UByteArray & guid, const UINT32 size, con
return U_INVALID_PARAMETER;
pad = UByteArray(size - guid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00');
pad.prepend(guid);
pad = guid + pad;
EFI_FFS_FILE_HEADER* header = (EFI_FFS_FILE_HEADER*)pad.data();
uint32ToUint24(size, header->Size);
header->Attributes = 0x00;
@ -1087,7 +1088,8 @@ USTATUS FfsBuilder::buildFile(const UModelIndex & index, const UINT8 revision, c
if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
reconstructed += ht + ft;
reconstructed += UByteArray(1, (char)ht);
reconstructed += UByteArray(1, (char)ft);
}
return U_SUCCESS;
}
@ -1244,7 +1246,8 @@ USTATUS FfsBuilder::buildFile(const UModelIndex & index, const UINT8 revision, c
if (revision == 1 && fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
reconstructed += ht + ft;
reconstructed += UByteArray(1, (char)ht);
reconstructed += UByteArray(1, (char)ft);
}
// Set file state
@ -1372,22 +1375,21 @@ USTATUS FfsBuilder::buildSection(const UModelIndex & index, const UINT32 base, U
*(UINT32*)(header.data() + sizeof(EFI_GUID_DEFINED_SECTION)) = crc;
}
else {
msg(usprintf("buildSection: GUID defined section authentication info can become invalid")
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index);
const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
}
}
// Check for Intel signed section
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
&& UByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
msg(usprintf("buildSection: GUID defined section signature can become invalid")
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index);
const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
}
// Replace new section body
reconstructed = compressed;
}
else if (compression != COMPRESSION_ALGORITHM_NONE) {
msg(usprintf("buildSection: incorrectly required compression for section of type %1")
.arg(model->subtype(index)), index);
msg(usprintf("buildSection: incorrectly required compression for section of type %d", model->subtype(index)), index);
return U_INVALID_SECTION;
}
}

View file

@ -34,20 +34,20 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
extracted += model->tail(index);
}
else if (mode == EXTRACT_MODE_BODY) {
name += QObject::tr("_body");
name += UString("_body");
// Extract without header and tail
extracted.clear();
extracted += model->body(index);
}
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
name += QObject::tr("_body_unc");
name += UString("_body_unc");
// Extract without header and tail, uncompressed
extracted.clear();
// There is no need to redo decompression, we can use child items
for (int i = 0; i < model->rowCount(index); i++) {
UModelIndex childIndex = index.child(i, 0);
// Ensure 4-byte alignment of current section
extracted += UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size());
extracted += UByteArray(ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size(), '\x00');
// Add current section header, body and tail
extracted += model->header(childIndex);
extracted += model->body(childIndex);
@ -66,7 +66,6 @@ USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, con
return U_INVALID_PARAMETER;
USTATUS result;
UByteArray empty = "";
FfsParser parser(model);
UINT32 localOffset = model->offset(index) + model->header(index).size();
UModelIndex index_out;
@ -98,8 +97,8 @@ USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, con
}
else if (model->type(index) == Types::Padding) {
// Get info
QString name = usprintf("Padding");
QString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
UString name = usprintf("Padding");
UString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
// Add tree item
//!TODO UModelIndex fileIndex = model->addItem(Types::Padding, getPaddingType(body), COMPRESSION_ALGORITHM_NONE, name, "", info, UByteArray(), body, index, mode);
}

View file

@ -16,7 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "basetypes.h"
#include "ustring.h"
#include "ubytearray.h"
#include <sys/stat.h>
#include <fstream>
#ifdef WIN32
#include <direct.h>
@ -48,4 +50,20 @@ static inline bool changeDirectory(const UString & dir) {
}
#endif
static inline USTATUS readFileIntoArray(const UString & inPath, UByteArray &array) {
if (!isExistOnFs(inPath))
return U_FILE_OPEN;
std::ifstream inputFile(inPath.toLocal8Bit(), std::ios::in | std::ios::binary);
if (!inputFile)
return U_FILE_OPEN;
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
(std::istreambuf_iterator<char>()));
inputFile.close();
array = buffer;
return U_SUCCESS;
}
#endif

View file

@ -12,6 +12,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "guiddatabase.h"
#include "ubytearray.h"
#include "ffs.h"
#if defined(U_ENABLE_GUID_DATABASE_SUPPORT)
#include <map>
@ -86,27 +87,9 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
continue;
EFI_GUID guid;
unsigned long p0;
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
int err = std::sscanf(lineParts[0].toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
if (err == 0)
if (!ustringToGuid(lineParts[0], guid))
continue;
guid.Data1 = p0;
guid.Data2 = p1;
guid.Data3 = p2;
guid.Data4[0] = p3;
guid.Data4[1] = p4;
guid.Data4[2] = p5;
guid.Data4[3] = p6;
guid.Data4[4] = p7;
guid.Data4[5] = p8;
guid.Data4[6] = p9;
guid.Data4[7] = p10;
gGuidToUStringMap.insert(GuidToUStringMap::value_type(guid, lineParts[1]));
}