From 0169c8c904aace715c5eb2329d867d9f4f2d0a38 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 1 Sep 2018 10:29:46 +0300 Subject: [PATCH] Fix more builder issues and perform the initial UEFIReplace port --- .gitignore | 1 + UEFIExtract/uefidump.cpp | 8 +-- UEFIExtract/uefiextract_main.cpp | 17 ++--- UEFIFind/uefifind.cpp | 14 ++-- UEFIReplace/CMakeLists.txt | 69 +++++++++++++++++++ UEFIReplace/uefireplace.cpp | 113 +++++++++++++++++++++++++++++++ UEFIReplace/uefireplace.h | 42 ++++++++++++ UEFIReplace/uefireplace_main.cpp | 93 +++++++++++++++++++++++++ common/basetypes.h | 1 + common/bstrlib/bstrwrap.h | 1 + common/ffs.cpp | 28 ++++++++ common/ffs.h | 1 + common/ffsbuilder.cpp | 24 ++++--- common/ffsops.cpp | 11 ++- common/filesystem.h | 18 +++++ common/guiddatabase.cpp | 21 +----- unixbuild.sh | 1 + 17 files changed, 402 insertions(+), 61 deletions(-) create mode 100644 UEFIReplace/CMakeLists.txt create mode 100755 UEFIReplace/uefireplace.cpp create mode 100755 UEFIReplace/uefireplace.h create mode 100755 UEFIReplace/uefireplace_main.cpp diff --git a/.gitignore b/.gitignore index c02be11..c76b767 100644 --- a/.gitignore +++ b/.gitignore @@ -240,6 +240,7 @@ UEFITool/XCBuildData UEFIDump/UEFIDump UEFIExtract/UEFIExtract UEFIFind/UEFIFind +UEFIReplace/UEFIReplace .qmake.stash CMakeCache.txt CMakeFiles diff --git a/UEFIExtract/uefidump.cpp b/UEFIExtract/uefidump.cpp index 8280568..02d52ee 100644 --- a/UEFIExtract/uefidump.cpp +++ b/UEFIExtract/uefidump.cpp @@ -133,7 +133,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index) if (!data.isEmpty()) { std::ofstream file; 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.close(); } @@ -143,7 +143,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index) if (!data.isEmpty()) { std::ofstream file; 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.close(); } @@ -157,8 +157,8 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index) std::ofstream file; UString str = name + UString("_info.txt"); - file.open((const char*)str, std::ios::out); - file.write((const char*)info, info.length()); + file.open(str.toLocal8Bit(), std::ios::out); + file.write(info.toLocal8Bit(), info.length()); file.close(); dumped = true; diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 87c34ae..a7cdf80 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -36,17 +36,12 @@ int main(int argc, char *argv[]) if (argc > 1) { // Check that input file exists + USTATUS result; + UByteArray buffer; UString path = argv[1]; - if (!isExistOnFs(path)) - return U_FILE_OPEN; - - // Open the input file - std::ifstream inputFile(argv[1], std::ios::in | std::ios::binary); - if (!inputFile) - return U_FILE_OPEN; - std::vector buffer(std::istreambuf_iterator(inputFile), - (std::istreambuf_iterator())); - inputFile.close(); + result = readFileIntoArray(path, buffer); + if (result) + return result; // Hack to support legacy UEFIDump mode. if (argc == 3 && !std::strcmp(argv[2], "unpack")) { @@ -58,7 +53,7 @@ int main(int argc, char *argv[]) TreeModel model; FfsParser ffsParser(&model); // Parse input buffer - USTATUS result = ffsParser.parse(buffer); + result = ffsParser.parse(buffer); if (result) return result; diff --git a/UEFIFind/uefifind.cpp b/UEFIFind/uefifind.cpp index 141ee78..02e9c56 100644 --- a/UEFIFind/uefifind.cpp +++ b/UEFIFind/uefifind.cpp @@ -32,16 +32,10 @@ UEFIFind::~UEFIFind() USTATUS UEFIFind::init(const UString & path) { USTATUS result; - - if (!isExistOnFs(path)) - return U_FILE_OPEN; - - std::ifstream inputFile(path.toLocal8Bit(), std::ios::in | std::ios::binary); - if (!inputFile) - return U_FILE_OPEN; - std::vector buffer(std::istreambuf_iterator(inputFile), - (std::istreambuf_iterator())); - inputFile.close(); + UByteArray buffer; + result = readFileIntoArray(path, buffer); + if (result) + return result; result = ffsParser->parse(buffer); if (result) diff --git a/UEFIReplace/CMakeLists.txt b/UEFIReplace/CMakeLists.txt new file mode 100644 index 0000000..b6db1c9 --- /dev/null +++ b/UEFIReplace/CMakeLists.txt @@ -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}) diff --git a/UEFIReplace/uefireplace.cpp b/UEFIReplace/uefireplace.cpp new file mode 100755 index 0000000..ee9fd7d --- /dev/null +++ b/UEFIReplace/uefireplace.cpp @@ -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 + +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; +} diff --git a/UEFIReplace/uefireplace.h b/UEFIReplace/uefireplace.h new file mode 100755 index 0000000..22dd314 --- /dev/null +++ b/UEFIReplace/uefireplace.h @@ -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 +#include + +#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 diff --git a/UEFIReplace/uefireplace_main.cpp b/UEFIReplace/uefireplace_main.cpp new file mode 100755 index 0000000..b10e0de --- /dev/null +++ b/UEFIReplace/uefireplace_main.cpp @@ -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 +#include +#include +#include +#include + +#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(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; +} diff --git a/common/basetypes.h b/common/basetypes.h index bb1ba4e..c44b37c 100644 --- a/common/basetypes.h +++ b/common/basetypes.h @@ -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 diff --git a/common/bstrlib/bstrwrap.h b/common/bstrlib/bstrwrap.h index 781c018..e8e0d16 100644 --- a/common/bstrlib/bstrwrap.h +++ b/common/bstrlib/bstrwrap.h @@ -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); } diff --git a/common/ffs.cpp b/common/ffs.cpp index 7a84841..9b33269 100644 --- a/common/ffs.cpp +++ b/common/ffs.cpp @@ -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 + #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) diff --git a/common/ffs.h b/common/ffs.h index ab757d3..e1f05e8 100644 --- a/common/ffs.h +++ b/common/ffs.h @@ -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); diff --git a/common/ffsbuilder.cpp b/common/ffsbuilder.cpp index 1f45fba..3f9e054 100644 --- a/common/ffsbuilder.cpp +++ b/common/ffsbuilder.cpp @@ -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(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; } } diff --git a/common/ffsops.cpp b/common/ffsops.cpp index d7db94e..c906fa1 100644 --- a/common/ffsops.cpp +++ b/common/ffsops.cpp @@ -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); } diff --git a/common/filesystem.h b/common/filesystem.h index 1685a08..ecad466 100644 --- a/common/filesystem.h +++ b/common/filesystem.h @@ -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 +#include #ifdef WIN32 #include @@ -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 buffer(std::istreambuf_iterator(inputFile), + (std::istreambuf_iterator())); + inputFile.close(); + + array = buffer; + + return U_SUCCESS; +} + #endif diff --git a/common/guiddatabase.cpp b/common/guiddatabase.cpp index 646aab2..dd76367 100644 --- a/common/guiddatabase.cpp +++ b/common/guiddatabase.cpp @@ -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 @@ -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])); } diff --git a/unixbuild.sh b/unixbuild.sh index 2594f7d..f8a3e3d 100755 --- a/unixbuild.sh +++ b/unixbuild.sh @@ -115,5 +115,6 @@ mkdir -p dist || exit 1 build_tool UEFITool "$UEFITOOL_VER" uefitool.pro build_tool UEFIExtract "$UEFITOOL_VER" "" build_tool UEFIFind "$UEFITOOL_VER" "" +build_tool UEFIReplace "$UEFITOOL_VER" "" exit 0