From ff42cecb07fb35bded4d8814aa1d956eda868707 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej <schlej@live.de> Date: Fri, 14 Feb 2025 07:19:09 +0100 Subject: [PATCH] UEFIExtract: add support for extracting uncompressedData for tree items that have it --- UEFIExtract/ffsdumper.cpp | 28 +++++++++++++++++++++++++--- UEFIExtract/ffsdumper.h | 3 ++- UEFIExtract/uefiextract_main.cpp | 10 ++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/UEFIExtract/ffsdumper.cpp b/UEFIExtract/ffsdumper.cpp index 44e639b..030904a 100644 --- a/UEFIExtract/ffsdumper.cpp +++ b/UEFIExtract/ffsdumper.cpp @@ -59,7 +59,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path } if (currentPath != path) { - counterHeader = counterBody = counterRaw = counterInfo = 0; + counterHeader = counterBody = counterUncData = counterRaw = counterInfo = 0; currentPath = path; } @@ -68,7 +68,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path && (sectionType == IgnoreSectionType || model->subtype(index) == sectionType)) { if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_HEADER) - && !model->header(index).isEmpty()) { + && !model->hasEmptyHeader(index)) { fileList.insert(index); UString filename; @@ -91,7 +91,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path } if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_BODY) - && !model->body(index).isEmpty()) { + && !model->hasEmptyBody(index)) { fileList.insert(index); UString filename; if (counterBody == 0) @@ -112,6 +112,28 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path dumped = true; } + if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_UNC_DATA) + && !model->hasEmptyUncompressedData(index)) { + fileList.insert(index); + UString filename; + if (counterUncData == 0) + filename = usprintf("%s/unc_data.bin", path.toLocal8Bit()); + else + filename = usprintf("%s/unc_data_%d.bin", path.toLocal8Bit(), counterUncData); + counterUncData++; + + std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary); + if (!file) { + printf("Cannot open uncompressed data \"%s\".\n", (const char*)filename.toLocal8Bit()); + return U_FILE_OPEN; + } + + const UByteArray &data = model->uncompressedData(index); + file.write(data.constData(), data.size()); + + dumped = true; + } + if (dumpMode == DUMP_FILE) { UModelIndex fileIndex = index; if (model->type(fileIndex) != Types::File) { diff --git a/UEFIExtract/ffsdumper.h b/UEFIExtract/ffsdumper.h index 8b2a7ec..85d619a 100644 --- a/UEFIExtract/ffsdumper.h +++ b/UEFIExtract/ffsdumper.h @@ -30,6 +30,7 @@ public: DUMP_CURRENT, DUMP_ALL, DUMP_BODY, + DUMP_UNC_DATA, DUMP_HEADER, DUMP_INFO, DUMP_FILE @@ -48,7 +49,7 @@ private: TreeModel* model; UString currentPath; bool dumped; - int counterHeader, counterBody, counterRaw, counterInfo; + int counterHeader, counterBody, counterUncData, counterRaw, counterInfo; std::set<UModelIndex> fileList; }; #endif // FFSDUMPER_H diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 78db042..e0ccab2 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -42,7 +42,7 @@ void print_usage() << " UEFIExtract imagefile guids - only generate GUID database, no dump or report needed." << std::endl << " UEFIExtract imagefile GUID_1 ... [ -o FILE_1 ... ] [ -m MODE_1 ... ] [ -t TYPE_1 ... ] -" << std::endl << " Dump only FFS file(s) with specific GUID(s), without report or GUID database." << std::endl - << " Type is section type or FF to ignore. Mode is one of: all, body, header, info, file." << std::endl + << " Type is section type or FF to ignore. Mode is one of: all, body, unc_data, header, info, file." << 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; } @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) // Parse input buffer result = ffsParser.parse(buffer); if (result) - return result; + return (int)result; ffsParser.outputInfo(); @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) else if (argc == 3 && !std::strcmp(argv[2], "guids")) { GuidDatabase db = guidDatabaseFromTreeRecursive(&model, model.index(0, 0)); if (!db.empty()) { - return guidDatabaseExportToFile(path + UString(".guids.csv"), db); + return (int)guidDatabaseExportToFile(path + UString(".guids.csv"), db); } } // Generate report, no dump or GUID database @@ -175,6 +175,8 @@ int main(int argc, char *argv[]) modes.push_back(FfsDumper::DUMP_ALL); else if (!std::strcmp(arg, "body")) modes.push_back(FfsDumper::DUMP_BODY); + else if (!std::strcmp(arg, "unc_data")) + modes.push_back(FfsDumper::DUMP_UNC_DATA); else if (!std::strcmp(arg, "header")) modes.push_back(FfsDumper::DUMP_HEADER); else if (!std::strcmp(arg, "info")) @@ -208,7 +210,7 @@ int main(int argc, char *argv[]) } } - return lastError; + return (int)lastError; } // If parameters are different, show version and usage information