diff --git a/UEFIExtract/ffsdumper.cpp b/UEFIExtract/ffsdumper.cpp index 3c86cab..07ee5ca 100644 --- a/UEFIExtract/ffsdumper.cpp +++ b/UEFIExtract/ffsdumper.cpp @@ -13,16 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "ffsdumper.h" -FfsDumper::FfsDumper(TreeModel* treeModel) - : model(treeModel), dumped(false) -{ -} - -FfsDumper::~FfsDumper() -{ -} - -USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const bool dumpAll, const UString & guid) +USTATUS FfsDumper::dump(const QModelIndex & root, const QString & path, const bool dumpAll, const QString & guid) { dumped = false; UINT8 result = recursiveDump(root, path, dumpAll, guid); @@ -33,7 +24,7 @@ USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const bo return U_SUCCESS; } -USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path, const bool dumpAll, const UString & guid) +USTATUS FfsDumper::recursiveDump(const QModelIndex & index, const QString & path, const bool dumpAll, const QString & guid) { if (!index.isValid()) return U_INVALID_PARAMETER; @@ -43,62 +34,60 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path guidToUString(*(const EFI_GUID*)model->header(index).constData()) == guid || guidToUString(*(const EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData()) == guid) { - if (dir.cd(QString(path))) + if (dir.cd(path)) return U_DIR_ALREADY_EXIST; - if (!dir.mkpath(QString(path))) + if (!dir.mkpath(path)) return U_DIR_CREATE; QFile file; if (dumpAll || model->rowCount(index) == 0) { // Dump if leaf item or dumpAll is true if (!model->header(index).isEmpty()) { - file.setFileName(QString(path) + UString("/header.bin")); + file.setFileName(QObject::tr("%1/header.bin").arg(path)); if (!file.open(QFile::WriteOnly)) return U_FILE_OPEN; - QByteArray ba(model->header(index).constData(), model->header(index).size()); - file.write(ba); + file.write(model->header(index)); file.close(); } if (!model->body(index).isEmpty()) { - file.setFileName(QString(path) + UString("/body.bin")); + file.setFileName(QObject::tr("%1/body.bin").arg(path)); if (!file.open(QFile::WriteOnly)) return U_FILE_OPEN; - QByteArray ba(model->body(index).constData(), model->body(index).size()); - file.write(ba); + file.write(model->body(index)); file.close(); } } - + // Always dump info - UString info = UString("Type: ") + itemTypeToUString(model->type(index)) + UString("\n") - + UString("Subtype: ") + itemSubtypeToUString(model->type(index), model->subtype(index)) + UString("\n") - + (model->text(index).isEmpty() ? UString("") : UString("Text: ") + model->text(index) + UString("\n")) - + model->info(index) + UString("\n"); - file.setFileName(QString(path) + UString("/info.txt")); + QString info = QObject::tr("Type: %1\nSubtype: %2\n%3%4\n") + .arg(itemTypeToUString(model->type(index))) + .arg(itemSubtypeToUString(model->type(index), model->subtype(index))) + .arg(model->text(index).isEmpty() ? QObject::tr("") : QObject::tr("Text: %1\n").arg(model->text(index))) + .arg(model->info(index)); + file.setFileName(QObject::tr("%1/info.txt").arg(path)); if (!file.open(QFile::Text | QFile::WriteOnly)) return U_FILE_OPEN; - file.write(info.toLocal8Bit()); + file.write(info.toLatin1()); file.close(); dumped = true; } UINT8 result; for (int i = 0; i < model->rowCount(index); i++) { - UModelIndex childIndex = index.child(i, 0); + QModelIndex childIndex = index.child(i, 0); bool useText = FALSE; if (model->type(childIndex) != Types::Volume) useText = !model->text(childIndex).isEmpty(); - UString childPath = path + usprintf("/%u ", i) + (useText ? model->text(childIndex) : model->name(childIndex)); + QString childPath = QString("%1/%2 %3").arg(path).arg(i).arg(useText ? model->text(childIndex) : model->name(childIndex)); result = recursiveDump(childIndex, childPath, dumpAll, guid); if (result) return result; } return U_SUCCESS; - } diff --git a/UEFIExtract/ffsdumper.h b/UEFIExtract/ffsdumper.h index 007e9f0..f45946e 100644 --- a/UEFIExtract/ffsdumper.h +++ b/UEFIExtract/ffsdumper.h @@ -14,10 +14,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef FFSDUMPER_H #define FFSDUMPER_H - +#include #include -#include "../common/ubytearray.h" -#include "../common/ustring.h" +#include +#include +#include + #include "../common/basetypes.h" #include "../common/treemodel.h" #include "../common/ffs.h" @@ -25,15 +27,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. class FfsDumper { public: - explicit FfsDumper(TreeModel * treeModel); - ~FfsDumper(); + explicit FfsDumper(TreeModel * treeModel) : model(treeModel), dumped(false) {} + ~FfsDumper() {}; - USTATUS dump(const UModelIndex & root, const UString & path, const bool dumpAll = false, const UString & guid = UString()); + USTATUS dump(const QModelIndex & root, const QString & path, const bool dumpAll = false, const QString & guid = QString()); private: - USTATUS recursiveDump(const UModelIndex & root, const UString & path, const bool dumpAll, const UString & guid); + USTATUS recursiveDump(const QModelIndex & root, const QString & path, const bool dumpAll, const QString & guid); TreeModel* model; bool dumped; }; - #endif // FFSDUMPER_H diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 7782d8d..f30b116 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -1,21 +1,18 @@ /* uefiextract_main.cpp - Copyright (c) 2016, Nikolaj Schlej. 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 <../common/ustring.h> +#include + #include "../common/ffsparser.h" #include "../common/ffsreport.h" #include "../common/fitparser.h" @@ -35,23 +32,20 @@ int main(int argc, char *argv[]) if (a.arguments().length() > 1) { // Check that input file exists - UString path(a.arguments().at(1).toLatin1()); - QString qpath = QString(path); - QFileInfo fileInfo(qpath); + QString path = a.arguments().at(1); + QFileInfo fileInfo(path); if (!fileInfo.exists()) return U_FILE_OPEN; // Open the input file QFile inputFile; - inputFile.setFileName(qpath); + inputFile.setFileName(path); if (!inputFile.open(QFile::ReadOnly)) return U_FILE_OPEN; - - // Read and close the file - QByteArray b = inputFile.readAll(); - inputFile.close(); - UByteArray buffer(b.constData(), b.size()); + // Read and close the file + QByteArray buffer = inputFile.readAll(); + inputFile.close(); // Create model and ffsParser TreeModel model; @@ -62,13 +56,13 @@ int main(int argc, char *argv[]) return result; // Show ffsParser's messages - std::vector > messages = ffsParser.getMessages(); + std::vector > messages = ffsParser.getMessages(); for (size_t i = 0; i < messages.size(); i++) { - std::cout << (const char*)messages[i].first.toLocal8Bit() << std::endl; + std::cout << messages[i].first.toLatin1().constData() << std::endl; } // Get last VTF - UModelIndex lastVtf = ffsParser.getLastVtf(); + QModelIndex lastVtf = ffsParser.getLastVtf(); if (lastVtf.isValid()) { // Create fitParser FitParser fitParser(&model); @@ -76,57 +70,59 @@ int main(int argc, char *argv[]) result = fitParser.parse(model.index(0, 0), lastVtf); if (U_SUCCESS == result) { // Show fitParser's messages - std::vector > fitMessages = fitParser.getMessages(); + std::vector > fitMessages = fitParser.getMessages(); for (size_t i = 0; i < fitMessages.size(); i++) { - std::cout << (const char*)fitMessages[i].first.toLocal8Bit() << std::endl; + std::cout << fitMessages[i].first.toLatin1().constData() << std::endl; } // Show FIT table - std::vector > fitTable = fitParser.getFitTable(); + std::vector > fitTable = fitParser.getFitTable(); if (fitTable.size()) { std::cout << "-------------------------------------------------------------------" << std::endl; std::cout << " Address | Size | Ver | Type | CS " << std::endl; std::cout << "-------------------------------------------------------------------" << std::endl; for (size_t i = 0; i < fitTable.size(); i++) { - std::cout << (const char*)fitTable[i][0].toLocal8Bit() << " | " - << (const char*)fitTable[i][1].toLocal8Bit() << " | " - << (const char*)fitTable[i][2].toLocal8Bit() << " | " - << (const char*)fitTable[i][3].toLocal8Bit() << " | " - << (const char*)fitTable[i][4].toLocal8Bit() << std::endl; + std::cout << fitTable[i][0].toLatin1().constData() << " | " + << fitTable[i][1].toLatin1().constData() << " | " + << fitTable[i][2].toLatin1().constData() << " | " + << fitTable[i][3].toLatin1().constData() << " | " + << fitTable[i][4].toLatin1().constData() << std::endl; } } } } - + // Create ffsReport FfsReport ffsReport(&model); - std::vector report = ffsReport.generate(); + std::vector report = ffsReport.generate(); if (report.size()) { - std::ofstream ofs; - ofs.open("report.txt", std::ofstream::out); - for (size_t i = 0; i < report.size(); i++) { - ofs << (const char*)report[i].toLocal8Bit() << std::endl; + QFile file; + file.setFileName(fileInfo.fileName().append(".report.txt")); + if (file.open(QFile::Text | QFile::WriteOnly)) { + for (size_t i = 0; i < report.size(); i++) { + file.write(report[i].toLatin1().append('\n')); + } + file.close(); } - ofs.close(); } - + // Create ffsDumper FfsDumper ffsDumper(&model); // Dump all non-leaf elements if (a.arguments().length() == 2) { - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData()) != U_SUCCESS); + return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS); } - else if (a.arguments().length() == 3 && a.arguments().at(2) == UString("all")) { // Dump everything - return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData(), true) != U_SUCCESS); + else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("all")) { // Dump everything + return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != U_SUCCESS); } - else if (a.arguments().length() == 3 && a.arguments().at(2) == UString("none")) { // Skip dumping + else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("none")) { // Skip dumping return 0; } else { // Dump specific files UINT32 returned = 0; for (int i = 2; i < a.arguments().length(); i++) { - result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump2").toLatin1().constData(), true, a.arguments().at(i).toLatin1().constData()); + result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true, a.arguments().at(i)); if (result) returned |= (1 << (i - 1)); } @@ -136,14 +132,12 @@ int main(int argc, char *argv[]) return 0; } else { // Show version and usage information - std::cout << "UEFIExtract 0.12.1" << std::endl << std::endl + std::cout << "UEFIExtract 0.12.2" << std::endl << std::endl << "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder" << std::endl << " UEFIExtract imagefile all - generate report and dump all tree items" << std::endl << " UEFIExtract imagefile none - only generate report, no dump needed" << std::endl << " UIFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s)" << std::endl - << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl << std::endl; + << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl; return 1; } - -return 0; -} +} \ No newline at end of file diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp index a16c592..58f9775 100644 --- a/common/ffsreport.cpp +++ b/common/ffsreport.cpp @@ -55,7 +55,7 @@ USTATUS FfsReport::generateRecursive(std::vector & report, UModelIndex UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16) + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) + usprintf("| %08X | %08X | ", data.size(), crc) - + UString('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) + + urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) ); // Information on child items diff --git a/common/ustring.cpp b/common/ustring.cpp index 8ff2533..6591d26 100644 --- a/common/ustring.cpp +++ b/common/ustring.cpp @@ -23,6 +23,11 @@ UString usprintf(const char* fmt, ...) va_end(vl); return msg; }; + +UString urepeated(char c, int len) +{ + return UString(len, c); +} #else /* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ #if defined(__WATCOMC__) || defined(_MSC_VER) @@ -91,4 +96,9 @@ UString usprintf(const char* fmt, ...) return msg; } + +UString urepeated(char c, int len) +{ + return UString(c, len); +} #endif diff --git a/common/ustring.h b/common/ustring.h index 171c7ec..f304db6 100644 --- a/common/ustring.h +++ b/common/ustring.h @@ -26,5 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #endif // QT_CORE_LIB UString usprintf(const char* fmt, ...); +UString urepeated(char c, int len); #endif // USTRING_H