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

1
.gitignore vendored
View file

@ -240,6 +240,7 @@ UEFITool/XCBuildData
UEFIDump/UEFIDump UEFIDump/UEFIDump
UEFIExtract/UEFIExtract UEFIExtract/UEFIExtract
UEFIFind/UEFIFind UEFIFind/UEFIFind
UEFIReplace/UEFIReplace
.qmake.stash .qmake.stash
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles

View file

@ -133,7 +133,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
if (!data.isEmpty()) { if (!data.isEmpty()) {
std::ofstream file; std::ofstream file;
UString str = name + UString("_header.bin"); UString str = name + UString("_header.bin");
file.open((const char*)str, std::ios::out | std::ios::binary); file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
file.write(data.constData(), data.size()); file.write(data.constData(), data.size());
file.close(); file.close();
} }
@ -143,7 +143,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
if (!data.isEmpty()) { if (!data.isEmpty()) {
std::ofstream file; std::ofstream file;
UString str = name + UString("_body.bin"); UString str = name + UString("_body.bin");
file.open((const char*)str, std::ios::out | std::ios::binary); file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
file.write(data.constData(), data.size()); file.write(data.constData(), data.size());
file.close(); file.close();
} }
@ -157,8 +157,8 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
std::ofstream file; std::ofstream file;
UString str = name + UString("_info.txt"); UString str = name + UString("_info.txt");
file.open((const char*)str, std::ios::out); file.open(str.toLocal8Bit(), std::ios::out);
file.write((const char*)info, info.length()); file.write(info.toLocal8Bit(), info.length());
file.close(); file.close();
dumped = true; dumped = true;

View file

@ -36,17 +36,12 @@ int main(int argc, char *argv[])
if (argc > 1) { if (argc > 1) {
// Check that input file exists // Check that input file exists
USTATUS result;
UByteArray buffer;
UString path = argv[1]; UString path = argv[1];
if (!isExistOnFs(path)) result = readFileIntoArray(path, buffer);
return U_FILE_OPEN; if (result)
return result;
// Open the input file
std::ifstream inputFile(argv[1], 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();
// Hack to support legacy UEFIDump mode. // Hack to support legacy UEFIDump mode.
if (argc == 3 && !std::strcmp(argv[2], "unpack")) { if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
@ -58,7 +53,7 @@ int main(int argc, char *argv[])
TreeModel model; TreeModel model;
FfsParser ffsParser(&model); FfsParser ffsParser(&model);
// Parse input buffer // Parse input buffer
USTATUS result = ffsParser.parse(buffer); result = ffsParser.parse(buffer);
if (result) if (result)
return result; return result;

View file

@ -32,16 +32,10 @@ UEFIFind::~UEFIFind()
USTATUS UEFIFind::init(const UString & path) USTATUS UEFIFind::init(const UString & path)
{ {
USTATUS result; USTATUS result;
UByteArray buffer;
if (!isExistOnFs(path)) result = readFileIntoArray(path, buffer);
return U_FILE_OPEN; if (result)
return result;
std::ifstream inputFile(path.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();
result = ffsParser->parse(buffer); result = ffsParser->parse(buffer);
if (result) if (result)

View file

@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.0)
PROJECT(UEFIReplace)
SET(PROJECT_SOURCES
uefireplace_main.cpp
uefireplace.cpp
../common/guiddatabase.cpp
../common/types.cpp
../common/descriptor.cpp
../common/ffs.cpp
../common/nvram.cpp
../common/nvramparser.cpp
../common/ffsparser.cpp
../common/ffsbuilder.cpp
../common/ffsops.cpp
../common/peimage.cpp
../common/treeitem.cpp
../common/treemodel.cpp
../common/utility.cpp
../common/LZMA/LzmaCompress.c
../common/LZMA/LzmaDecompress.c
../common/LZMA/SDK/C/LzFind.c
../common/LZMA/SDK/C/LzmaDec.c
../common/LZMA/SDK/C/LzmaEnc.c
../common/Tiano/EfiTianoDecompress.c
../common/Tiano/EfiTianoCompress.c
../common/Tiano/EfiTianoCompressLegacy.c
../common/ustring.cpp
../common/sha256.c
../common/bstrlib/bstrlib.c
../common/bstrlib/bstrwrap.cpp
)
SET(PROJECT_HEADERS
uefireplace.h
../common/guiddatabase.h
../common/basetypes.h
../common/descriptor.h
../common/gbe.h
../common/me.h
../common/ffs.h
../common/nvram.h
../common/nvramparser.h
../common/ffsparser.h
../common/ffsbuilder.h
../common/ffsops.h
../common/peimage.h
../common/types.h
../common/treeitem.h
../common/treemodel.h
../common/utility.h
../common/LZMA/LzmaDecompress.h
../common/Tiano/EfiTianoDecompress.h
../common/LZMA/LzmaCompress.h
../common/Tiano/EfiTianoCompress.h
../common/ubytearray.h
../common/ustring.h
../common/bootguard.h
../common/sha256.h
../common/filesystem.h
../common/bstrlib/bstrlib.h
../common/bstrlib/bstrwrap.h
../version.h
)
ADD_DEFINITIONS(-DU_ENABLE_NVRAM_PARSING_SUPPORT -DU_ENABLE_FIT_PARSING_SUPPORT -DU_ENABLE_GUID_DATABASE_SUPPORT)
ADD_EXECUTABLE(UEFIReplace ${PROJECT_SOURCES} ${PROJECT_HEADERS})

113
UEFIReplace/uefireplace.cpp Executable file
View file

@ -0,0 +1,113 @@
/* uefireplace.cpp
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "uefireplace.h"
#include <cstring>
UEFIReplace::UEFIReplace()
{
model = new TreeModel();
ffsParser = new FfsParser(model);
ffsBuilder = new FfsBuilder(model, ffsParser);
ffsOps = new FfsOperations(model);
}
UEFIReplace::~UEFIReplace()
{
delete ffsOps;
delete ffsBuilder;
delete ffsParser;
delete model;
}
USTATUS UEFIReplace::replace(const UString & inPath, const EFI_GUID & guid, const UINT8 sectionType, const UString & contentPath, const UString & outPath, bool replaceAsIs, bool replaceOnce)
{
UByteArray buffer;
USTATUS result;
result = readFileIntoArray(inPath, buffer);
if (result)
return result;
result = ffsParser->parse(buffer);
if (result)
return result;
UByteArray contents;
result = readFileIntoArray(contentPath, contents);
if (result)
return result;
result = replaceInFile(model->index(0, 0), guid, sectionType, contents,
replaceAsIs ? REPLACE_MODE_AS_IS : REPLACE_MODE_BODY, replaceOnce);
if (result)
return result;
UByteArray reconstructed;
result = ffsBuilder->build(model->index(0,0), reconstructed);
if (result)
return result;
if (reconstructed == buffer)
return U_NOTHING_TO_PATCH;
std::ofstream outputFile;
outputFile.open(outPath.toLocal8Bit(), std::ios::out | std::ios::binary);
outputFile.write(reconstructed.constData(), reconstructed.size());
outputFile.close();
return U_SUCCESS;
}
USTATUS UEFIReplace::replaceInFile(const UModelIndex & index, const EFI_GUID & guid, const UINT8 sectionType, const UByteArray & newData, const UINT8 mode, bool replaceOnce)
{
if (!model || !index.isValid())
return U_INVALID_PARAMETER;
bool patched = false;
if (model->subtype(index) == sectionType) {
UModelIndex fileIndex = index;
if (model->type(index) != Types::File)
fileIndex = model->findParentOfType(index, Types::File);
UByteArray fileGuid = model->header(fileIndex).left(sizeof(EFI_GUID));
bool guidMatch = fileGuid.size() == sizeof(EFI_GUID) &&
!std::memcmp((const EFI_GUID*)fileGuid.constData(), &guid, sizeof(EFI_GUID));
if (!guidMatch && sectionType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
UByteArray subGuid = model->header(index).mid(sizeof(UINT32), sizeof(EFI_GUID));
guidMatch = subGuid.size() == sizeof(EFI_GUID) &&
!std::memcmp((const EFI_GUID*)subGuid.constData(), &guid, sizeof(EFI_GUID));;
}
if (guidMatch && model->action(index) != Actions::Replace) {
UByteArray newDataCopy = newData;
USTATUS result = ffsOps->replace(index, newDataCopy, mode);
if (replaceOnce || (result != U_SUCCESS && result != U_NOTHING_TO_PATCH))
return result;
patched = result == U_SUCCESS;
}
}
if (model->rowCount(index) > 0) {
for (int i = 0; i < model->rowCount(index); i++) {
USTATUS result = replaceInFile(index.child(i, 0), guid, sectionType, newData, mode, replaceOnce);
if (result == U_SUCCESS) {
patched = true;
if (replaceOnce)
break;
} else if (result != U_NOTHING_TO_PATCH) {
return result;
}
}
}
return patched ? U_SUCCESS : U_NOTHING_TO_PATCH;
}

42
UEFIReplace/uefireplace.h Executable file
View file

@ -0,0 +1,42 @@
/* uefireplace.h
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef __UEFIREPLACE_H__
#define __UEFIREPLACE_H__
#include <iterator>
#include <set>
#include "../common/basetypes.h"
#include "../common/ustring.h"
#include "../common/filesystem.h"
#include "../common/ffs.h"
#include "../common/ffsparser.h"
#include "../common/ffsops.h"
#include "../common/ffsbuilder.h"
#include "../common/utility.h"
class UEFIReplace
{
public:
UEFIReplace();
~UEFIReplace();
USTATUS replace(const UString & inPath, const EFI_GUID & guid, const UINT8 sectionType, const UString & contentPath, const UString & outPath, bool replaceAsIs, bool replaceOnce);
private:
USTATUS replaceInFile(const UModelIndex & index, const EFI_GUID & guid, const UINT8 sectionType, const UByteArray & contents, const UINT8 mode, bool replaceOnce);
TreeModel* model;
FfsParser* ffsParser;
FfsBuilder* ffsBuilder;
FfsOperations* ffsOps;
};
#endif

View file

@ -0,0 +1,93 @@
/* uefireplace_main.cpp
Copyright (c) 2017, mxxxc. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include "../version.h"
#include "uefireplace.h"
int main(int argc, char *argv[])
{
UEFIReplace r;
USTATUS result = U_SUCCESS;
if (argc < 5) {
std::cout << "UEFIReplace " PROGRAM_VERSION " - UEFI image file replacement utility" << std::endl << std::endl <<
"Usage: UEFIReplace image_file guid section_type contents_file [-o output] [-all] [-asis]" << std::endl;
return U_SUCCESS;
}
EFI_GUID guid;
UString uuid = UString(argv[2]);
char *converted = const_cast<char *>(argv[3]);
UINT8 sectionType = (UINT8)std::strtol(argv[3], &converted, 16);
if (converted == argv[3] || !ustringToGuid(uuid, guid)) {
result = U_INVALID_PARAMETER;
} else {
UString output = UString(argv[1]) + ".patched";
bool replaceOnce = true;
bool replaceAsIs = false;
for (int i = 5, sz = argc; i < sz; i++) {
if ((!std::strcmp(argv[i], "-o") || !std::strcmp(argv[i], "--output")) && i + 1 < sz) {
output = argv[i+1];
i++;
} else if (!std::strcmp(argv[i], "-all")) {
replaceOnce = false;
} else if (!std::strcmp(argv[i], "-asis")) {
replaceAsIs = true;
} else {
result = U_INVALID_PARAMETER;
}
}
if (result == U_SUCCESS) {
result = r.replace(argv[1], guid, sectionType, argv[4], output, replaceAsIs, replaceOnce);
}
}
switch (result) {
case U_SUCCESS:
std::cout << "File replaced" << std::endl;
break;
case U_INVALID_PARAMETER:
std::cout << "Function called with invalid parameter" << std::endl;
break;
case U_INVALID_FILE:
std::cout << "Invalid/corrupted file specified" << std::endl;
break;
case U_INVALID_SECTION:
std::cout << "Invalid/corrupted section specified" << std::endl;
break;
case U_NOTHING_TO_PATCH:
std::cout << "No replacements can be applied to input file" << std::endl;
break;
case U_NOT_IMPLEMENTED:
std::cout << "Can't replace body of this section type" << std::endl;
break;
case U_FILE_OPEN:
std::cout << "Input file not found" << std::endl;
break;
case U_FILE_READ:
std::cout << "Input file can't be read" << std::endl;
break;
case U_FILE_WRITE:
std::cout << "Output file can't be written" << std::endl;
break;
default:
std::cout << "Error " << result << std::endl;
}
return result;
}

View file

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

View file

@ -363,6 +363,7 @@ struct CBString : public tagbstring {
// QString compatibility methods // QString compatibility methods
const char *toLocal8Bit() const { return *this; } const char *toLocal8Bit() const { return *this; }
bool contains(const char *str) { return find(str) >= 0; }
bool isEmpty() const { return slen == 0; } bool isEmpty() const { return slen == 0; }
void clear() { *this = ""; } void clear() { *this = ""; }
CBString left(int len) const { return midstr(0, len); } 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. WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include <cstdio>
#include "ffs.h" #include "ffs.h"
#include "guiddatabase.h" #include "guiddatabase.h"
@ -69,6 +71,32 @@ UString guidToUString(const EFI_GUID & guid, bool convertToString)
guid.Data4[7]); 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) UString fileTypeToUString(const UINT8 type)
{ {
switch (type) switch (type)

View file

@ -23,6 +23,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#pragma pack(push,1) #pragma pack(push,1)
extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true); 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 fileTypeToUString(const UINT8 type);
extern UString sectionTypeToUString(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; return result;
break; break;
default: 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; return U_UNKNOWN_ITEM_TYPE;
} }
@ -978,7 +978,8 @@ USTATUS FfsBuilder::buildNvramStore(const UModelIndex & index, UByteArray & stor
// Recalculate store checksum // Recalculate store checksum
UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32)); UINT32 calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
// Write new checksum // 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) { else if(type == Types::EvsaStore) {
UByteArray store = header + body; UByteArray store = header + body;
@ -1048,7 +1049,7 @@ USTATUS FfsBuilder::buildPadFile(const UByteArray & guid, const UINT32 size, con
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
pad = UByteArray(size - guid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00'); 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(); EFI_FFS_FILE_HEADER* header = (EFI_FFS_FILE_HEADER*)pad.data();
uint32ToUint24(size, header->Size); uint32ToUint24(size, header->Size);
header->Attributes = 0x00; header->Attributes = 0x00;
@ -1087,7 +1088,8 @@ USTATUS FfsBuilder::buildFile(const UModelIndex & index, const UINT8 revision, c
if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header; UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File; UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
reconstructed += ht + ft; reconstructed += UByteArray(1, (char)ht);
reconstructed += UByteArray(1, (char)ft);
} }
return U_SUCCESS; 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) { if (revision == 1 && fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header; UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File; UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
reconstructed += ht + ft; reconstructed += UByteArray(1, (char)ht);
reconstructed += UByteArray(1, (char)ft);
} }
// Set file state // 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; *(UINT32*)(header.data() + sizeof(EFI_GUID_DEFINED_SECTION)) = crc;
} }
else { else {
msg(usprintf("buildSection: GUID defined section authentication info can become invalid") const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index); msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
} }
} }
// Check for Intel signed section // Check for Intel signed section
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
&& UByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) { && UByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
msg(usprintf("buildSection: GUID defined section signature can become invalid") const char *guidStr = guidToUString(guidDefinedHeader->SectionDefinitionGuid).toLocal8Bit();
.arg(guidToUString(guidDefinedHeader->SectionDefinitionGuid)), index); msg(usprintf("buildSection: GUID defined section signature can become invalid (%s)", guidStr), index);
} }
// Replace new section body // Replace new section body
reconstructed = compressed; reconstructed = compressed;
} }
else if (compression != COMPRESSION_ALGORITHM_NONE) { else if (compression != COMPRESSION_ALGORITHM_NONE) {
msg(usprintf("buildSection: incorrectly required compression for section of type %1") msg(usprintf("buildSection: incorrectly required compression for section of type %d", model->subtype(index)), index);
.arg(model->subtype(index)), index);
return U_INVALID_SECTION; return U_INVALID_SECTION;
} }
} }

View file

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

View file

@ -12,6 +12,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "guiddatabase.h" #include "guiddatabase.h"
#include "ubytearray.h" #include "ubytearray.h"
#include "ffs.h"
#if defined(U_ENABLE_GUID_DATABASE_SUPPORT) #if defined(U_ENABLE_GUID_DATABASE_SUPPORT)
#include <map> #include <map>
@ -86,27 +87,9 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
continue; continue;
EFI_GUID guid; EFI_GUID guid;
if (!ustringToGuid(lineParts[0], 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)
continue; 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])); gGuidToUStringMap.insert(GuidToUStringMap::value_type(guid, lineParts[1]));
} }

View file

@ -115,5 +115,6 @@ mkdir -p dist || exit 1
build_tool UEFITool "$UEFITOOL_VER" uefitool.pro build_tool UEFITool "$UEFITOOL_VER" uefitool.pro
build_tool UEFIExtract "$UEFITOOL_VER" "" build_tool UEFIExtract "$UEFITOOL_VER" ""
build_tool UEFIFind "$UEFITOOL_VER" "" build_tool UEFIFind "$UEFITOOL_VER" ""
build_tool UEFIReplace "$UEFITOOL_VER" ""
exit 0 exit 0