Improve firmware parser and tool robustness

closes #241
This commit is contained in:
joevt 2021-10-07 18:51:39 +03:00 committed by vit9696
parent e14547c497
commit f9c35f77a6
41 changed files with 415 additions and 324 deletions

2
.gitignore vendored
View File

@ -238,6 +238,7 @@ UEFITool.app/
UEFITool/XCBuildData
UEFIDump/UEFIDump
UEFIExtract/UEFIExtract
UEFIExtract/guids.csv
UEFIFind/UEFIFind
.qmake.stash
CMakeCache.txt
@ -250,3 +251,4 @@ CMakeScripts
UEFITool/qrc_uefitool.cpp
XcodeQT5
XcodeQT6
*.dSYM

View File

@ -21,16 +21,20 @@ USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const Du
counterHeader = counterBody = counterRaw = counterInfo = 0;
fileList.clear();
if (changeDirectory(path))
if (changeDirectory(path)) {
printf("Directory \"%s\" already exists.\n", (const char*)path.toLocal8Bit());
return U_DIR_ALREADY_EXIST;
}
currentPath = path;
USTATUS result = recursiveDump(root, path, dumpMode, sectionType, guid);
if (result) {
printf("Error %lu returned from recursiveDump (directory \"%s\").\n", result, (const char*)path.toLocal8Bit());
return result;
} else if (!dumped) {
removeDirectory(path);
printf("Removed directory \"%s\" since nothing was dumped.\n", (const char*)path.toLocal8Bit());
return U_ITEM_NOT_FOUND;
}
@ -48,8 +52,10 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
guidToUString(readUnaligned((const EFI_GUID*)model->header(index).constData())) == guid ||
guidToUString(readUnaligned((const EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData())) == guid) {
if (!changeDirectory(path) && !makeDirectory(path))
if (!changeDirectory(path) && !makeDirectory(path)) {
printf("Cannot use directory \"%s\" (recursiveDump part 1).\n", (const char*)path.toLocal8Bit());
return U_DIR_CREATE;
}
if (currentPath != path) {
counterHeader = counterBody = counterRaw = counterInfo = 0;
@ -72,8 +78,10 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
counterHeader++;
std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary);
if (!file)
if (!file) {
printf("Cannot open header \"%s\".\n", (const char*)filename.toLocal8Bit());
return U_FILE_OPEN;
}
const UByteArray &data = model->header(index);
file.write(data.constData(), data.size());
@ -92,8 +100,10 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
counterBody++;
std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary);
if (!file)
if (!file) {
printf("Cannot open body \"%s\".\n", (const char*)filename.toLocal8Bit());
return U_FILE_OPEN;
}
const UByteArray &data = model->body(index);
file.write(data.constData(), data.size());
@ -121,8 +131,10 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
counterRaw++;
std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary);
if (!file)
if (!file) {
printf("Cannot open file \"%s\".\n", (const char*)filename.toLocal8Bit());
return U_FILE_OPEN;
}
const UByteArray &headerData = model->header(fileIndex);
const UByteArray &bodyData = model->body(fileIndex);
@ -155,8 +167,10 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
counterInfo++;
std::ofstream file(filename.toLocal8Bit());
if (!file)
if (!file) {
printf("Cannot open info \"%s\".\n", (const char*)filename.toLocal8Bit());
return U_FILE_OPEN;
}
file << info.toLocal8Bit();
@ -174,15 +188,20 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
UString childPath = path;
if (dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT) {
if (!changeDirectory(path) && !makeDirectory(path))
if (!changeDirectory(path) && !makeDirectory(path)) {
printf("Cannot use directory \"%s\" (recursiveDump part 2).\n", (const char*)path.toLocal8Bit());
return U_DIR_CREATE;
}
childPath = usprintf("%s/%d %s", path.toLocal8Bit(), i,
(useText ? model->text(childIndex) : model->name(childIndex)).toLocal8Bit());
UString name = usprintf("%d %s", i, (useText ? model->text(childIndex) : model->name(childIndex)).toLocal8Bit());
fixFileName (name, false);
childPath = usprintf("%s/%s", path.toLocal8Bit(), name.toLocal8Bit());
}
result = recursiveDump(childIndex, childPath, dumpMode, sectionType, guid);
if (result)
if (result) {
printf("Error %lu returned from recursiveDump (child directory \"%s\").\n", result, (const char*)childPath.toLocal8Bit());
return result;
}
}
return U_SUCCESS;

View File

@ -41,27 +41,8 @@ USTATUS UEFIDumper::dump(const UByteArray & buffer, const UString & inPath, cons
USTATUS result = ffsParser.parse(buffer);
if (result)
return result;
// Show ffsParser messages
std::vector<std::pair<UString, UModelIndex> > messages = ffsParser.getMessages();
for (size_t i = 0; i < messages.size(); i++) {
std::cout << messages[i].first << std::endl;
}
// Show FIT table
std::vector<std::pair<std::vector<UString>, UModelIndex > > fitTable = ffsParser.getFitTable();
if (fitTable.size()) {
std::cout << "-------------------------------------------------------------------------" << std::endl;
std::cout << " Address | Size | Ver | CS | Type / Info " << std::endl;
std::cout << "-------------------------------------------------------------------------" << std::endl;
for (size_t i = 0; i < fitTable.size(); i++) {
std::cout << fitTable[i].first[0].toLocal8Bit() << " | "
<< fitTable[i].first[1].toLocal8Bit() << " | "
<< fitTable[i].first[2].toLocal8Bit() << " | "
<< fitTable[i].first[3].toLocal8Bit() << " | "
<< fitTable[i].first[4].toLocal8Bit() << " | "
<< fitTable[i].first[5].toLocal8Bit() << std::endl;
}
}
ffsParser.outputInfo();
// Create ffsReport
FfsReport ffsReport(&model);
@ -123,8 +104,10 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
name = orgName + UString("_") + usprintf("%03d", i);
}
if (!nameFound)
if (!nameFound) {
printf("Cannot find unique name for \"%s\".\n", (const char*)orgName.toLocal8Bit());
return U_INVALID_PARAMETER; //TODO: replace with proper errorCode
}
// Add header and body only for leaf sections
if (model.rowCount(index) == 0) {

View File

@ -57,36 +57,7 @@ int main(int argc, char *argv[])
if (result)
return result;
// Show ffsParser's messages
std::vector<std::pair<UString, UModelIndex> > messages = ffsParser.getMessages();
for (size_t i = 0; i < messages.size(); i++) {
std::cout << messages[i].first.toLocal8Bit() << std::endl;
}
// Get last VTF
std::vector<std::pair<std::vector<UString>, UModelIndex > > fitTable = ffsParser.getFitTable();
if (fitTable.size()) {
std::cout << "---------------------------------------------------------------------------" << std::endl;
std::cout << " Address | Size | Ver | CS | Type / Info " << std::endl;
std::cout << "---------------------------------------------------------------------------" << std::endl;
for (size_t i = 0; i < fitTable.size(); i++) {
std::cout << fitTable[i].first[0].toLocal8Bit() << " | "
<< fitTable[i].first[1].toLocal8Bit() << " | "
<< fitTable[i].first[2].toLocal8Bit() << " | "
<< fitTable[i].first[3].toLocal8Bit() << " | "
<< fitTable[i].first[4].toLocal8Bit() << " | "
<< fitTable[i].first[5].toLocal8Bit() << std::endl;
}
}
// Get security info
UString secInfo = ffsParser.getSecurityInfo();
if (!secInfo.isEmpty()) {
std::cout << "------------------------------------------------------------------------" << std::endl;
std::cout << "Security Info" << std::endl;
std::cout << "------------------------------------------------------------------------" << std::endl;
std::cout << secInfo << std::endl;
}
ffsParser.outputInfo();
// Create ffsDumper
FfsDumper ffsDumper(&model);

View File

@ -59,7 +59,7 @@ USTATUS UEFIFind::find(const UINT8 mode, const bool count, const UString & hexPa
if (count) {
if (!files.empty())
result += usprintf("%d\n", files.size());
result += usprintf("%lu\n", files.size());
return U_SUCCESS;
}

View File

@ -13,6 +13,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsfinder.h"
#if QT_VERSION_MAJOR >= 6
#include <QRegularExpression>
#else
#include <QRegExp>
#endif
USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode)
{
//TODO: use FfsUtils.

View File

@ -16,12 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <vector>
#if QT_VERSION_MAJOR >= 6
#include <QRegularExpression>
#else
#include <QRegExp>
#endif
#include "../common/ubytearray.h"
#include "../common/ustring.h"
#include "../common/basetypes.h"

View File

@ -46,7 +46,7 @@ void GuidLineEdit::keyPressEvent(QKeyEvent * event)
if (txt[i] != QChar('-'))
txt[i] = QChar('.');
}
else
else
txt[pos] = QChar('.');
setCursorPosition(0);

View File

@ -32,8 +32,8 @@ CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar
_charPos = charPos;
_newChar = newChar;
_cmd = cmd;
_wasChanged = false;
_oldChar = ' ';
_wasChanged = false;
_oldChar = ' ';
}
bool CharCommand::mergeWith(const QUndoCommand *command)

View File

@ -124,10 +124,10 @@ void QHexEdit::setAsciiArea(bool asciiArea)
{
if (!asciiArea)
_editAreaIsAscii = false;
_asciiArea = asciiArea;
_asciiArea = asciiArea;
adjust();
setCursorPosition(_cursorPosition);
viewport()->update();
viewport()->update();
}
bool QHexEdit::asciiArea()
@ -753,8 +753,8 @@ void QHexEdit::keyPressEvent(QKeyEvent *event)
QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex();
for (qint64 idx = 32; idx < ba.size(); idx += 33)
ba.insert((int)idx, "\n");
if(_upperCase)
ba = ba.toUpper();
if(_upperCase)
ba = ba.toUpper();
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(ba);
}

View File

@ -647,6 +647,7 @@ void UEFITool::openImageFile(QString path)
// Parse the image
USTATUS result = ffsParser->parse(buffer);
showParserMessages();
if (result) {
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToUString(result), QMessageBox::Ok);
@ -655,6 +656,8 @@ void UEFITool::openImageFile(QString path)
else
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
ffsParser->outputInfo();
// Enable or disable FIT tab
showFitTable();
@ -796,7 +799,7 @@ void UEFITool::showParserMessages()
#if QT_VERSION_MAJOR < 6
std::pair<QString, QModelIndex> msg;
foreach (msg, messages) {
#else
for (const auto &msg : messages) {

View File

@ -41,6 +41,7 @@ HEADERS += uefitool.h \
../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \
../common/Tiano/EfiTianoCompress.h \
../common/uinttypes.h \
../common/ustring.h \
../common/ubytearray.h \
../common/bootguard.h \
@ -123,7 +124,5 @@ FORMS += uefitool.ui \
RESOURCES += uefitool.qrc
RC_FILE = uefitool.rc
ICON = icons/uefitool.icns
ICONFILE.files = icons/uefitool.icns
ICONFILE.path = Contents/Resources
QMAKE_BUNDLE_DATA += ICONFILE
QMAKE_INFO_PLIST = Info.plist

View File

@ -188,7 +188,7 @@ typedef struct EFI_TIME_ {
UINT8 Reserved0;
UINT32 Nanosecond; // Nanosecond: 0 - 999,999,999
INT16 TimeZone; // TimeZone: -1440 to 1440 or UNSPECIFIED (0x07FF)
UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2)
UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2)
UINT8 Reserved1;
} EFI_TIME;

View File

@ -22,6 +22,7 @@ extern "C" {
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include "../uinttypes.h"
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) && !defined (__BORLANDC__)
@ -138,9 +139,9 @@ extern int brtrimws (bstring b);
extern int btrimws (bstring b);
#if !defined (BSTRLIB_NOVSNP)
extern bstring bformat (const char * fmt, ...);
extern int bformata (bstring b, const char * fmt, ...);
extern int bassignformat (bstring b, const char * fmt, ...);
extern bstring bformat (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2);
extern int bformata (bstring b, const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3);
extern int bassignformat (bstring b, const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3);
extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
#define bvformata(ret, b, fmt, lastarg) { \

View File

@ -52,6 +52,7 @@
#include <stdlib.h>
#include "bstrlib.h"
#include "../ubytearray.h"
#include "../uinttypes.h"
#ifdef __cplusplus
@ -331,8 +332,8 @@ struct CBString : public tagbstring {
void trunc (int len);
// Miscellaneous methods.
void format (const char * fmt, ...);
void formata (const char * fmt, ...);
void format (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3);
void formata (const char * fmt, ...) ATTRIBUTE_FORMAT_(printf, 2, 3);
void fill (int length, unsigned char fill = ' ');
void repeat (int count);
void ltrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n")));
@ -364,10 +365,13 @@ struct CBString : public tagbstring {
// QString compatibility methods
const char *toLocal8Bit() const { return *this; }
bool contains(const char *str) { return find(str) >= 0; }
bool endsWith(const char *str) { int len = strlen(str); return (slen >= len && (find(str, slen - len) == (slen - len))); }
bool isEmpty() const { return slen == 0; }
void clear() { *this = ""; }
CBString left(int len) const { return midstr(0, len); }
CBString mid(int pos, int len) const { return midstr(pos, len); }
CBString chopped(int len) const { return midstr(slen - len, len); }
void chop(int len) { trunc(((slen > len) ? slen - len : 0)); }
static CBString fromUtf16(const unsigned short* str) {
// Naive implementation assuming that only ASCII LE part of UCS2 is used, str may not be aligned.
CBString msg;

View File

@ -275,8 +275,8 @@ typedef struct EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE_ {
// Integrity check
typedef union {
struct {
UINT8 Header;
UINT8 File;
UINT8 Header;
UINT8 File;
} Checksum;
UINT16 TailReference; // Revision 1
UINT16 Checksum16; // Revision 2
@ -406,7 +406,7 @@ typedef struct EFI_COMMON_SECTION_HEADER2_ {
// Apple common section header
typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
UINT8 Size[3];
UINT8 Size[3];
UINT8 Type;
UINT32 Reserved; // Must be 0x7FFF for this header to be used
} EFI_COMMON_SECTION_HEADER_APPLE;

View File

@ -79,7 +79,7 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
}
// Rebuild or Replace
else if (model->action(index) == Actions::Rebuild
else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) {
if (model->rowCount(index)) {
// Clear the supplied UByteArray
@ -272,7 +272,7 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
return U_SUCCESS;
}
// Rebuild or Replace
else if (model->action(index) == Actions::Rebuild
else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) {
// Rebuild if there is at least 1 child
if (model->rowCount(index)) {

View File

@ -10,15 +10,11 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
// A workaround for compilers not supporting c++11 and c11
// for using PRIX64.
#define __STDC_FORMAT_MACROS
#include "ffsparser.h"
#include <map>
#include <algorithm>
#include <inttypes.h>
#include <iostream>
#include "descriptor.h"
#include "ffs.h"
@ -26,7 +22,6 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "me.h"
#include "fit.h"
#include "nvram.h"
#include "utility.h"
#include "peimage.h"
#include "parsingdata.h"
#include "types.h"
@ -34,6 +29,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "nvramparser.h"
#include "meparser.h"
#include "uinttypes.h"
#ifndef QT_CORE_LIB
namespace Qt {
@ -67,6 +63,7 @@ struct BPDT_PARTITION_INFO {
struct CPD_PARTITION_INFO {
CPD_ENTRY ptEntry;
UINT8 type;
bool hasMetaData;
UModelIndex index;
friend bool operator< (const CPD_PARTITION_INFO & lhs, const CPD_PARTITION_INFO & rhs){ return lhs.ptEntry.Offset.Offset < rhs.ptEntry.Offset.Offset; }
};
@ -164,7 +161,7 @@ USTATUS FfsParser::parseGenericImage(const UByteArray & buffer, const UINT32 loc
{
// Parse as generic UEFI image
UString name("UEFI image");
UString info = usprintf("Full size: %Xh (%u)", buffer.size(), buffer.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", buffer.size(), buffer.size());
// Add tree item
index = model->addItem(localOffset, Types::Image, Subtypes::UefiImage, name, UString(), info, UByteArray(), buffer, UByteArray(), Fixed, parent);
@ -211,7 +208,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOf
UByteArray body = capsule.mid(capsuleHeaderSize);
UString name("UEFI capsule");
UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
usprintf("\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
capsule.size(), capsule.size(),
capsuleHeaderSize, capsuleHeaderSize,
capsuleHeader->CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleImageSize - capsuleHeaderSize,
@ -243,7 +240,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOf
UByteArray body = capsule.mid(capsuleHeaderSize);
UString name("Toshiba capsule");
UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
usprintf("\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
capsule.size(), capsule.size(),
capsuleHeaderSize, capsuleHeaderSize,
capsuleHeader->FullSize - capsuleHeaderSize, capsuleHeader->FullSize - capsuleHeaderSize,
@ -284,7 +281,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOf
UByteArray body = capsule.mid(capsuleHeaderSize);
UString name("AMI Aptio capsule");
UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
usprintf("\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
capsule.size(), capsule.size(),
capsuleHeaderSize, capsuleHeaderSize,
capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize,
@ -488,7 +485,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
// Intel image
UString name("Intel image");
UString info = usprintf("Full size: %Xh (%u)\nFlash chips: %u\nRegions: %u\nMasters: %u\nPCH straps: %u\nPROC straps: %u",
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nFlash chips: %u\nRegions: %u\nMasters: %u\nPCH straps: %u\nPROC straps: %u",
intelImage.size(), intelImage.size(),
descriptorMap->NumberOfFlashChips + 1, //
descriptorMap->NumberOfRegions + 1, // Zero-based numbers in storage
@ -652,7 +649,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")",
padding.size(), padding.size());
// Add tree item
@ -684,7 +681,7 @@ USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 localOffs
UString name("GbE region");
const GBE_MAC_ADDRESS* mac = (const GBE_MAC_ADDRESS*)gbe.constData();
const GBE_VERSION* version = (const GBE_VERSION*)(gbe.constData() + GBE_VERSION_OFFSET);
UString info = usprintf("Full size: %Xh (%u)\nMAC: %02X:%02X:%02X:%02X:%02X:%02X\nVersion: %u.%u",
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nMAC: %02X:%02X:%02X:%02X:%02X:%02X\nVersion: %u.%u",
gbe.size(), gbe.size(),
mac->vendor[0], mac->vendor[1], mac->vendor[2],
mac->device[0], mac->device[1], mac->device[2],
@ -705,7 +702,7 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
// Get info
UString name("ME region");
UString info = usprintf("Full size: %Xh (%u)", me.size(), me.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", me.size(), me.size());
// Parse region
bool versionFound = true;
@ -768,7 +765,7 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs
// Get info
UString name("PDR region");
UString info = usprintf("Full size: %Xh (%u)", pdr.size(), pdr.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", pdr.size(), pdr.size());
// Add tree item
index = model->addItem(localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent);
@ -789,7 +786,7 @@ USTATUS FfsParser::parseDevExp1Region(const UByteArray & devExp1, const UINT32 l
// Get info
UString name("DevExp1 region");
UString info = usprintf("Full size: %Xh (%u)", devExp1.size(), devExp1.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", devExp1.size(), devExp1.size());
bool emptyRegion = false;
// Check for empty region
@ -816,7 +813,7 @@ USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & re
// Get info
UString name = itemSubtypeToUString(Types::Region, subtype) + UString(" region");
UString info = usprintf("Full size: %Xh (%u)", region.size(), region.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", region.size(), region.size());
// Add tree item
index = model->addItem(localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent);
@ -832,7 +829,7 @@ USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 localOf
// Get info
UString name("BIOS region");
UString info = usprintf("Full size: %Xh (%u)", bios.size(), bios.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", bios.size(), bios.size());
// Add tree item
index = model->addItem(localOffset, Types::Region, Subtypes::BiosRegion, name, UString(), info, UByteArray(), bios, UByteArray(), Fixed, parent);
@ -877,7 +874,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Get info
UByteArray padding = data.left(prevItemOffset);
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
model->addItem(headerSize, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -898,7 +895,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
model->addItem(headerSize + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -911,7 +908,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
UModelIndex paddingIndex = model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -951,7 +948,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Get info
name = UString("BPDT region");
info = usprintf("Full size: %Xh (%u)", bpdtStore.size(), bpdtStore.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", bpdtStore.size(), bpdtStore.size());
// Add tree item
UModelIndex bpdtIndex = model->addItem(headerSize + itemOffset, Types::BpdtStore, 0, name, UString(), info, UByteArray(), bpdtStore, UByteArray(), Fixed, index);
@ -984,7 +981,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -1029,8 +1026,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
return U_INVALID_PARAMETER;
// Check that there is space for the volume header
if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {
msg(usprintf("%s: input volume size %Xh (%u) is smaller than volume header size 40h (64)", __FUNCTION__, volume.size(), volume.size()));
if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {
msg(usprintf("%s: input volume size %" PRIXQ "h (%" PRIuQ ") is smaller than volume header size 40h (64)", __FUNCTION__, volume.size(), volume.size()));
return U_INVALID_VOLUME;
}
@ -1344,7 +1341,7 @@ USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 l
continue;
}
// Calculate alternative volume size using it's BlockMap
// Calculate alternative volume size using its BlockMap
nextItemAlternativeSize = 0;
const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(data.constData() + offset - EFI_FV_SIGNATURE_OFFSET + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
while (entry->NumBlocks != 0 && entry->Length != 0) {
@ -1421,7 +1418,7 @@ USTATUS FfsParser::parseVolumeNonUefiData(const UByteArray & data, const UINT32
return U_INVALID_PARAMETER;
// Get info
UString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", data.size(), data.size());
// Add padding tree item
UModelIndex paddingIndex = model->addItem(localOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), data, UByteArray(), Fixed, index);
@ -1520,7 +1517,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
UByteArray free = freeSpace.left(i);
// Get info
UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", free.size(), free.size());
// Add free space item
model->addItem(volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index);
@ -1531,7 +1528,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
}
else {
// Get info
UString info = usprintf("Full size: %Xh (%u)", freeSpace.size(), freeSpace.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", freeSpace.size(), freeSpace.size());
// Add free space item
model->addItem(volumeHeaderSize + fileOffset, Types::FreeSpace, 0, UString("Volume free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Movable, index);
@ -1764,7 +1761,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
}
info = UString("File GUID: ") + guidToUString(fileHeader->Name, false) +
usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh",
usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nTail size: %" PRIXQ "h (%" PRIuQ ")\nState: %02Xh",
fileHeader->Type,
fileHeader->Attributes,
header.size() + body.size() + tail.size(), header.size() + body.size() + tail.size(),
@ -1943,7 +1940,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
UByteArray free = body.left(nonEmptyByteOffset);
// Get info
UString info = usprintf("Full size: %Xh (%u)", free.size(), free.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", free.size(), free.size());
// Add tree item
model->addItem(headerSize, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), free, UByteArray(), Movable, index);
@ -1956,7 +1953,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
UByteArray padding = body.mid(nonEmptyByteOffset);
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
UModelIndex dataIndex = model->addItem(headerSize + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -2004,7 +2001,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
UByteArray padding = sections.mid(sectionOffset);
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
UModelIndex dataIndex = model->addItem(headerSize + sectionOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -2137,7 +2134,7 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI
// Get info
UString name = sectionTypeToUString(type) + UString(" section");
UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
UString info = usprintf("Type: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %Xh (%u)\nBody size: %" PRIXQ "h (%" PRIuQ ")",
type,
section.size(), section.size(),
headerSize, headerSize,
@ -2205,7 +2202,7 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons
// Get info
UString name = sectionTypeToUString(sectionHeader->Type) + UString(" section");
UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nCompression type: %02Xh\nDecompressed size: %Xh (%u)",
UString info = usprintf("Type: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %Xh (%u)\nBody size: %" PRIXQ "h (%" PRIuQ ")\nCompression type: %02Xh\nDecompressed size: %Xh (%u)",
sectionHeader->Type,
section.size(), section.size(),
headerSize, headerSize,
@ -2385,7 +2382,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
// Get info
UString name = guidToUString(guid);
UString info = UString("Section GUID: ") + guidToUString(guid, false) +
usprintf("\nType: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nAttributes: %04Xh",
usprintf("\nType: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nData offset: %Xh\nAttributes: %04Xh",
sectionHeader->Type,
section.size(), section.size(),
header.size(), header.size(),
@ -2480,7 +2477,7 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
// Get info
UString name = sectionTypeToUString(type) + (" section");
UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nSubtype GUID: ",
UString info = usprintf("Type: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nSubtype GUID: ",
type,
section.size(), section.size(),
header.size(), header.size(),
@ -2554,7 +2551,7 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U
// Get info
UString name = sectionTypeToUString(type) + (" section");
UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nBuild number: %u",
UString info = usprintf("Type: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nBuild number: %u",
type,
section.size(), section.size(),
header.size(), header.size(),
@ -2620,7 +2617,7 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const
// Get info
UString name = sectionTypeToUString(type) + (" section");
UString info = usprintf("Type: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nPostcode: %Xh",
UString info = usprintf("Type: %02Xh\nFull size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nPostcode: %Xh",
type,
section.size(), section.size(),
header.size(), header.size(),
@ -2701,11 +2698,11 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
// Check reported uncompressed size
if (uncompressedSize != (UINT32)decompressed.size()) {
msg(usprintf("parseCompressedSectionBody: decompressed size stored in header %Xh (%u) differs from actual %Xh (%u)",
msg(usprintf("parseCompressedSectionBody: decompressed size stored in header %Xh (%u) differs from actual %" PRIXQ "h (%" PRIuQ ")",
uncompressedSize, uncompressedSize,
decompressed.size(), decompressed.size()),
index);
model->addInfo(index, usprintf("\nActual decompressed size: %Xh (%u)", decompressed.size(), decompressed.size()));
model->addInfo(index, usprintf("\nActual decompressed size: %" PRIXQ "h (%" PRIuQ ")", decompressed.size(), decompressed.size()));
}
// Check for undecided compression algorithm, this is a special case
@ -2793,7 +2790,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
}
info += UString("\nCompression algorithm: ") + compressionTypeToUString(algorithm);
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
}
// LZMA compressed section
else if (baGuid == EFI_GUIDED_SECTION_LZMA) {
@ -2805,7 +2802,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
if (algorithm == COMPRESSION_ALGORITHM_LZMA) {
info += UString("\nCompression algorithm: LZMA");
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize);
}
else {
@ -2823,7 +2820,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
if (algorithm == COMPRESSION_ALGORITHM_LZMAF86) {
info += UString("\nCompression algorithm: LZMAF86");
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize);
}
else {
@ -2840,7 +2837,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
}
info += UString("\nCompression algorithm: GZip");
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
}
// Add info
@ -3370,18 +3367,18 @@ USTATUS FfsParser::addInfoRecursive(const UModelIndex & index)
model->addInfo(index, usprintf("Offset: %Xh\n", model->offset(index)), false);
// Add current base if the element is not compressed
// or it's compressed, but it's parent isn't
// or it's compressed, but its parent isn't
if ((!model->compressed(index)) || (index.parent().isValid() && !model->compressed(index.parent()))) {
// Add physical address of the whole item or it's header and data portions separately
// Add physical address of the whole item or its header and data portions separately
UINT64 address = addressDiff + model->base(index);
if (address <= 0xFFFFFFFFUL) {
UINT32 headerSize = (UINT32)model->header(index).size();
if (headerSize) {
model->addInfo(index, usprintf("Data address: %08Xh\n", address + headerSize),false);
model->addInfo(index, usprintf("Header address: %08Xh\n", address), false);
model->addInfo(index, usprintf("Data address: %08llXh\n", address + headerSize),false);
model->addInfo(index, usprintf("Header address: %08llXh\n", address), false);
}
else {
model->addInfo(index, usprintf("Address: %08Xh\n", address), false);
model->addInfo(index, usprintf("Address: %08llXh\n", address), false);
}
}
// Add base
@ -3863,7 +3860,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
// Add entry to fitTable
currentStrings.push_back(usprintf("%016" PRIX64 "h", currentEntry->Address));
currentStrings.push_back(usprintf("%08Xh", currentEntrySize, currentEntrySize));
currentStrings.push_back(usprintf("%08Xh", currentEntrySize));
currentStrings.push_back(usprintf("%04Xh", currentEntry->Version));
currentStrings.push_back(usprintf("%02Xh", currentEntry->Checksum));
currentStrings.push_back(fitEntryTypeToUString(currentEntry->Type));
@ -3916,7 +3913,7 @@ void FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & found,
for (INT32 offset = (INT32)model->body(index).indexOf(FIT_SIGNATURE);
offset >= 0;
offset = (INT32)model->body(index).indexOf(FIT_SIGNATURE, offset + 1)) {
// FIT candidate found, calculate it's physical address
// FIT candidate found, calculate its physical address
UINT32 fitAddress = (UINT32)(model->base(index) + (UINT32)addressDiff + model->header(index).size() + (UINT32)offset);
// Check FIT address to be stored in the last VTF
@ -3988,12 +3985,12 @@ USTATUS FfsParser::parseFitEntryAcm(const UByteArray & acm, const UINT32 localOf
// Add ACM header info
UString acmInfo;
acmInfo += usprintf(" found at base %Xh\n"
"ModuleType: %04Xh ModuleSubtype: %04Xh HeaderLength: %08Xh\n"
"ModuleType: %04Xh ModuleSubtype: %04Xh HeaderLength: %08lXh\n"
"HeaderVersion: %08Xh ChipsetId: %04Xh Flags: %04Xh\n"
"ModuleVendor: %04Xh Date: %02X.%02X.%04X ModuleSize: %08Xh\n"
"ModuleVendor: %04Xh Date: %02X.%02X.%04X ModuleSize: %08lXh\n"
"EntryPoint: %08Xh AcmSvn: %04Xh Unknown1: %08Xh\n"
"Unknown2: %08Xh GdtBase: %08Xh GdtMax: %08Xh\n"
"SegSel: %08Xh KeySize: %08Xh Unknown3: %08Xh",
"SegSel: %08Xh KeySize: %08lXh Unknown3: %08lXh",
model->base(parent) + localOffset,
header->ModuleType,
header->ModuleSubtype,
@ -4197,7 +4194,7 @@ USTATUS FfsParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
securityInfo += usprintf(
"\nInitial Boot Block Element found at base %Xh\n"
"Tag: __IBBS__ Version: %02Xh Unknown: %02Xh\n"
"Flags: %08Xh IbbMchBar: %08Xh VtdBar: %08Xh\n"
"Flags: %08Xh IbbMchBar: %08llXh VtdBar: %08llXh\n"
"PmrlBase: %08Xh PmrlLimit: %08Xh EntryPoint: %08Xh",
model->base(parent) + localOffset + elementOffset,
elementHeader->Version,
@ -4361,7 +4358,7 @@ USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index)
if (offset < bodySize) {
// Get info
UString name = UString("Padding");
UString info = usprintf("Full size: %Xh (%u)", ucode.size(), ucode.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", ucode.size(), ucode.size());
// Add tree item
model->addItem(headerSize + offset, Types::Padding, getPaddingType(ucode), name, UString(), info, UByteArray(), ucode, UByteArray(), Fixed, index);
@ -4482,7 +4479,7 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
// Add info
UString name("Intel microcode");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: 0h (0u)\nBody size: %Xh (%u)\nTail size: 0h (0u)\n"
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: 0h (0u)\nBody size: %" PRIXQ "h (%" PRIuQ ")\nTail size: 0h (0u)\n"
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nCPU flags: %02Xh\nChecksum: %08Xh, ",
microcodeBinary.size(), microcodeBinary.size(),
microcodeBinary.size(), microcodeBinary.size(),
@ -4501,7 +4498,7 @@ USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const
if (msgInvalidChecksum)
msg(usprintf("%s: invalid microcode checksum %08Xh, should be %08Xh", __FUNCTION__, ucodeHeader->Checksum, calculated), index);
if (msgUnknownOrDamagedMicrocodeTail)
msg(usprintf("%s: extended header of size %Xh (%u) found, but it's damaged or has unknown format", __FUNCTION__, tail.size(), tail.size()), index);
msg(usprintf("%s: extended header of size %" PRIXQ "h (%" PRIuQ ") found, but it's damaged or has unknown format", __FUNCTION__, tail.size(), tail.size()), index);
// No need to parse the body further for now
return U_SUCCESS;
@ -4533,7 +4530,7 @@ USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 local
UByteArray body = region.mid(sizeof(BPDT_HEADER), ptBodySize);
UString name = UString("BPDT partition table");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u\nVersion: %2Xh\n"
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %Xh (%u)\nNumber of entries: %u\nVersion: %2Xh\n"
"IFWI version: %Xh\nFITC version: %u.%u.%u.%u",
ptSize, ptSize,
header.size(), header.size(),
@ -4558,7 +4555,7 @@ USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 local
// Get info
name = bpdtEntryTypeToUString(ptEntry->Type);
info = usprintf("Full size: %Xh (%u)\nType: %Xh\nPartition offset: %Xh\nPartition length: %Xh",
info = usprintf("Full size: %lXh (%lu)\nType: %Xh\nPartition offset: %Xh\nPartition length: %Xh",
sizeof(BPDT_ENTRY), sizeof(BPDT_ENTRY),
ptEntry->Type,
ptEntry->Offset,
@ -4591,7 +4588,7 @@ USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 local
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")",
partition.size(), partition.size());
// Add tree item
@ -4632,7 +4629,7 @@ make_partition_table_consistent:
goto make_partition_table_consistent;
}
else {
msg(usprintf("%s: BPDT partition can't fit into it's region, truncated", __FUNCTION__), partitions[i].index);
msg(usprintf("%s: BPDT partition can't fit into its region, truncated", __FUNCTION__), partitions[i].index);
partitions[i].ptEntry.Size = regionSize - (UINT32)partitions[i].ptEntry.Offset;
}
}
@ -4673,7 +4670,7 @@ make_partition_table_consistent:
UByteArray partition = region.mid(partitions[i].ptEntry.Offset, partitions[i].ptEntry.Size);
UByteArray signature = partition.left(sizeof(UINT32));
UString info = usprintf("Full size: %Xh (%u)\nType: %Xh",
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh",
partition.size(), partition.size(),
partitions[i].ptEntry.Type) +
UString("\nSplit sub-partition first part: ") + (partitions[i].ptEntry.SplitSubPartitionFirstPart ? "Yes" : "No") +
@ -4708,7 +4705,7 @@ make_partition_table_consistent:
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")",
padding.size(), padding.size());
// Add tree item
@ -4723,7 +4720,7 @@ make_partition_table_consistent:
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")",
padding.size(), padding.size());
// Add tree item
@ -4770,7 +4767,7 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
UByteArray header = region.left(ptHeaderSize);
UByteArray body = region.mid(ptHeaderSize);
UString name = usprintf("CPD partition table");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u\n"
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nNumber of entries: %u\n"
"Header version: %02X\nEntry version: %02X",
region.size(), region.size(),
header.size(), header.size(),
@ -4792,11 +4789,8 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
UByteArray entry((const char*)cpdEntry, sizeof(CPD_ENTRY));
// Get info
name = usprintf("%c%c%c%c%c%c%c%c%c%c%c%c",
cpdEntry->EntryName[0], cpdEntry->EntryName[1], cpdEntry->EntryName[2], cpdEntry->EntryName[3],
cpdEntry->EntryName[4], cpdEntry->EntryName[5], cpdEntry->EntryName[6], cpdEntry->EntryName[7],
cpdEntry->EntryName[8], cpdEntry->EntryName[9], cpdEntry->EntryName[10], cpdEntry->EntryName[11]);
info = usprintf("Full size: %Xh (%u)\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
name = usprintf("%.12s", cpdEntry->EntryName);
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
entry.size(), entry.size(),
cpdEntry->Offset.Offset,
cpdEntry->Length)
@ -4814,6 +4808,7 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
partition.type = Types::CpdPartition;
partition.ptEntry = *cpdEntry;
partition.index = entryIndex;
partition.hasMetaData = false;
partitions.push_back(partition);
}
}
@ -4824,7 +4819,7 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")",
partition.size(), partition.size());
// Add tree item
@ -4839,15 +4834,12 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
// Because lenghts for all Huffmann-compressed partitions mean nothing at all, we need to split all partitions into 2 classes:
// 1. CPD manifest (should be the first)
// 2. Metadata entries (should begin right after partition manifest and end before any code partition)
UINT32 i = 1;
UINT32 i = 1; // manifest is index 0, .met partitions start at index 1
while (i < partitions.size()) {
name = usprintf("%c%c%c%c%c%c%c%c%c%c%c%c",
partitions[i].ptEntry.EntryName[0], partitions[i].ptEntry.EntryName[1], partitions[i].ptEntry.EntryName[2], partitions[i].ptEntry.EntryName[3],
partitions[i].ptEntry.EntryName[4], partitions[i].ptEntry.EntryName[5], partitions[i].ptEntry.EntryName[6], partitions[i].ptEntry.EntryName[7],
partitions[i].ptEntry.EntryName[8], partitions[i].ptEntry.EntryName[9], partitions[i].ptEntry.EntryName[10], partitions[i].ptEntry.EntryName[11]);
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
// Check if the current entry is metadata entry
if (!name.contains(".met")) {
if (!name.endsWith(".met")) {
// No need to parse further, all metadata partitions are parsed
break;
}
@ -4869,23 +4861,18 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
}
// Search down for corresponding code partition
// Construct it's name by replacing last 4 non-zero butes of the name with zeros
UINT32 j = 0;
for (UINT32 k = 11; k > 0 && j < 4; k--) {
if (name[k] != '\x00') {
name[k] = '\x00';
j++;
}
}
// Construct its name by removing the .met suffix
name.chop(4);
// Search
j = i + 1;
bool found = false;
UINT32 j = i + 1;
while (j < partitions.size()) {
if (name == usprintf("%c%c%c%c%c%c%c%c%c%c%c%c",
partitions[j].ptEntry.EntryName[0], partitions[j].ptEntry.EntryName[1], partitions[j].ptEntry.EntryName[2], partitions[j].ptEntry.EntryName[3],
partitions[j].ptEntry.EntryName[4], partitions[j].ptEntry.EntryName[5], partitions[j].ptEntry.EntryName[6], partitions[j].ptEntry.EntryName[7],
partitions[j].ptEntry.EntryName[8], partitions[j].ptEntry.EntryName[9], partitions[j].ptEntry.EntryName[10], partitions[j].ptEntry.EntryName[11])) {
// Found it, update it's Length if needed
UString namej = usprintf("%.12s", partitions[j].ptEntry.EntryName);
if (name == namej) {
found = true;
// Found it, update its Length if needed
if (partitions[j].ptEntry.Offset.HuffmanCompressed) {
partitions[j].ptEntry.Length = length;
}
@ -4894,12 +4881,17 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
partitions[j].ptEntry.Length, length), partitions[j].index);
partitions[j].ptEntry.Length = length; // Believe metadata
}
partitions[j].hasMetaData = true;
// No need to search further
break;
}
// Check the next partition
j++;
}
if (!found) {
msg(usprintf("%s: no code partition", __FUNCTION__), partitions[i].index);
}
// Check the next partition
i++;
}
@ -4937,13 +4929,27 @@ make_partition_table_consistent:
goto make_partition_table_consistent;
}
else {
msg(usprintf("%s: CPD partition can't fit into it's region, truncated", __FUNCTION__), partitions[i].index);
if (!partitions[i].hasMetaData && partitions[i].ptEntry.Offset.HuffmanCompressed) {
msg(usprintf("%s: CPD partition is compressed but doesn't have metadata and can't fit into its region, length adjusted", __FUNCTION__),
partitions[i].index);
}
else {
msg(usprintf("%s: CPD partition can't fit into its region, truncated", __FUNCTION__), partitions[i].index);
}
partitions[i].ptEntry.Length = (UINT32)region.size() - (UINT32)partitions[i].ptEntry.Offset.Offset;
}
}
// Check for intersection with previous partition
if (partitions[i].ptEntry.Offset.Offset < previousPartitionEnd) {
// Check if previous partition was compressed but did not have metadata
if (!partitions[i - 1].hasMetaData && partitions[i - 1].ptEntry.Offset.HuffmanCompressed) {
msg(usprintf("%s: CPD partition is compressed but doesn't have metadata, length adjusted", __FUNCTION__),
partitions[i - 1].index);
partitions[i - 1].ptEntry.Length = (UINT32)partitions[i].ptEntry.Offset.Offset - (UINT32)partitions[i - 1].ptEntry.Offset.Offset;
goto make_partition_table_consistent;
}
// Check if current partition is located inside previous one
if (partitions[i].ptEntry.Offset.Offset + partitions[i].ptEntry.Length <= previousPartitionEnd) {
msg(usprintf("%s: CPD partition is located inside another CPD partition, skipped", __FUNCTION__),
@ -4982,10 +4988,7 @@ make_partition_table_consistent:
UByteArray partition = region.mid(partitions[i].ptEntry.Offset.Offset, partitions[i].ptEntry.Length);
// Get info
name = usprintf("%c%c%c%c%c%c%c%c%c%c%c%c",
partitions[i].ptEntry.EntryName[0], partitions[i].ptEntry.EntryName[1], partitions[i].ptEntry.EntryName[2], partitions[i].ptEntry.EntryName[3],
partitions[i].ptEntry.EntryName[4], partitions[i].ptEntry.EntryName[5], partitions[i].ptEntry.EntryName[6], partitions[i].ptEntry.EntryName[7],
partitions[i].ptEntry.EntryName[8], partitions[i].ptEntry.EntryName[9], partitions[i].ptEntry.EntryName[10], partitions[i].ptEntry.EntryName[11]);
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
// It's a manifest
if (name.contains(".man")) {
@ -4997,8 +5000,8 @@ make_partition_table_consistent:
UByteArray body = partition.mid(header.size());
info += usprintf(
"\nHeader type: %u\nHeader length: %Xh (%u)\nHeader version: %Xh\nFlags: %08Xh\nVendor: %Xh\n"
"Date: %Xh\nSize: %Xh (%u)\nVersion: %u.%u.%u.%u\nSecurity version number: %u\nModulus size: %Xh (%u)\nExponent size: %Xh (%u)",
"\nHeader type: %u\nHeader length: %lXh (%lu)\nHeader version: %Xh\nFlags: %08Xh\nVendor: %Xh\n"
"Date: %Xh\nSize: %lXh (%lu)\nVersion: %u.%u.%u.%u\nSecurity version number: %u\nModulus size: %lXh (%lu)\nExponent size: %lXh (%lu)",
manifestHeader->HeaderType,
manifestHeader->HeaderLength * sizeof(UINT32), manifestHeader->HeaderLength * sizeof(UINT32),
manifestHeader->HeaderVersion,
@ -5021,13 +5024,13 @@ make_partition_table_consistent:
}
// It's a metadata
else if (name.contains(".met")) {
info = usprintf("Full size: %Xh (%u)\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
partition.size(), partition.size(),
partitions[i].ptEntry.Offset.Offset,
partitions[i].ptEntry.Length)
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
// Calculate SHA256 hash over the metadata and add it to it's info
// Calculate SHA256 hash over the metadata and add it to its info
UByteArray hash(SHA256_DIGEST_SIZE, '\x00');
sha256(partition.constData(), partition.size(), hash.data());
info += UString("\nMetadata hash: ") + UString(hash.toHex().constData());
@ -5040,13 +5043,13 @@ make_partition_table_consistent:
}
// It's a key
else if (name.contains(".key")) {
info = usprintf("Full size: %Xh (%u)\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
partition.size(), partition.size(),
partitions[i].ptEntry.Offset.Offset,
partitions[i].ptEntry.Length)
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
// Calculate SHA256 hash over the key and add it to it's info
// Calculate SHA256 hash over the key and add it to its info
UByteArray hash(SHA256_DIGEST_SIZE, '\x00');
sha256(partition.constData(), partition.size(), hash.data());
info += UString("\nHash: ") + UString(hash.toHex().constData());
@ -5059,13 +5062,13 @@ make_partition_table_consistent:
}
// It's a code
else {
info = usprintf("Full size: %Xh (%u)\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
partition.size(), partition.size(),
partitions[i].ptEntry.Offset.Offset,
partitions[i].ptEntry.Length)
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
// Calculate SHA256 hash over the code and add it to it's info
// Calculate SHA256 hash over the code and add it to its info
UByteArray hash(SHA256_DIGEST_SIZE, '\x00');
sha256(partition.constData(), partition.size(), hash.data());
info += UString("\nHash: ") + UString(hash.toHex().constData());
@ -5079,7 +5082,7 @@ make_partition_table_consistent:
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", partition.size(), partition.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", partition.size(), partition.size());
// Add tree item
model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);
@ -5107,7 +5110,7 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
UByteArray partition = body.mid(offset, extHeader->Length);
UString name = cpdExtensionTypeToUstring(extHeader->Type);
UString info = usprintf("Full size: %Xh (%u)\nType: %Xh", partition.size(), partition.size(), extHeader->Type);
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh", partition.size(), partition.size(), extHeader->Type);
// Parse Signed Package Info a bit further
UModelIndex extIndex;
@ -5117,14 +5120,14 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
const CPD_EXT_SIGNED_PACKAGE_INFO* infoHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO*)header.constData();
info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %Xh\n"
"Package name: %c%c%c%c\nVersion control number: %Xh\nSecurity version number: %Xh\n"
"Usage bitmap: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\n"
"Package name: %.4s\nVersion control number: %Xh\nSecurity version number: %Xh\n"
"Usage bitmap: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
partition.size(), partition.size(),
header.size(), header.size(),
body.size(), body.size(),
infoHeader->ExtensionType,
infoHeader->PackageName[0], infoHeader->PackageName[1], infoHeader->PackageName[2], infoHeader->PackageName[3],
infoHeader->PackageName,
infoHeader->Vcn,
infoHeader->Svn,
infoHeader->UsageBitmap[0], infoHeader->UsageBitmap[1], infoHeader->UsageBitmap[2], infoHeader->UsageBitmap[3],
@ -5142,15 +5145,15 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
// This hash is stored reversed
// Need to reverse it back to normal
UByteArray hash((const char*)&attrHeader->CompletePartitionHash, sizeof(attrHeader->CompletePartitionHash));
UByteArray hash((const char*)&attrHeader->CompletePartitionHash, attrHeader->HashSize);
std::reverse(hash.begin(), hash.end());
info = usprintf("Full size: %Xh (%u)\nType: %Xh\n"
"Partition name: %c%c%c%c\nPartition length: %Xh\nPartition version major: %Xh\nPartition version minor: %Xh\n"
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\n"
"Partition name: %.4s\nPartition length: %Xh\nPartition version major: %Xh\nPartition version minor: %Xh\n"
"Data format version: %Xh\nInstance ID: %Xh\nHash algorithm: %Xh\nHash size: %Xh\nAction on update: %Xh",
partition.size(), partition.size(),
attrHeader->ExtensionType,
attrHeader->PartitionName[0], attrHeader->PartitionName[1], attrHeader->PartitionName[2], attrHeader->PartitionName[3],
attrHeader->PartitionName,
attrHeader->CompletePartitionLength,
attrHeader->PartitionVersionMajor, attrHeader->PartitionVersionMinor,
attrHeader->DataFormatVersion,
@ -5169,17 +5172,22 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
// Add tree item
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
if (sizeof (attrHeader->CompletePartitionHash) != attrHeader->HashSize) {
msg(usprintf("%s: IFWI Partition Manifest hash size is %d, expected %lu", __FUNCTION__, attrHeader->HashSize, sizeof (attrHeader->CompletePartitionHash)), extIndex);
}
}
// Parse Module Attributes a bit further
else if (extHeader->Type == CPD_EXT_TYPE_MODULE_ATTRIBUTES) {
const CPD_EXT_MODULE_ATTRIBUTES* attrHeader = (const CPD_EXT_MODULE_ATTRIBUTES*)partition.constData();
int hashSize = partition.size() - offsetof(CPD_EXT_MODULE_ATTRIBUTES, ImageHash);
// This hash is stored reversed
// Need to reverse it back to normal
UByteArray hash((const char*)&attrHeader->ImageHash, sizeof(attrHeader->ImageHash));
UByteArray hash((const char*)&attrHeader->ImageHash, hashSize);
std::reverse(hash.begin(), hash.end());
info = usprintf("Full size: %Xh (%u)\nType: %Xh\n"
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\n"
"Compression type: %Xh\nUncompressed size: %Xh (%u)\nCompressed size: %Xh (%u)\nGlobal module ID: %Xh\nImage hash: ",
partition.size(), partition.size(),
attrHeader->ExtensionType,
@ -5190,6 +5198,9 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
// Add tree item
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
if (hashSize != sizeof (attrHeader->ImageHash)) {
msg(usprintf("%s: Module Attributes hash size is %d, expected %lu", __FUNCTION__, hashSize, sizeof (attrHeader->ImageHash)), extIndex);
}
}
// Parse everything else
else {
@ -5221,26 +5232,26 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
while (offset < (UINT32)body.size()) {
const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE* moduleHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE*)(body.constData() + offset);
if (sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) <= ((UINT32)body.size() - offset)) {
UByteArray module((const char*)moduleHeader, sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE));
UByteArray module((const char*)moduleHeader, sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) - sizeof (moduleHeader->MetadataHash) + moduleHeader->HashSize);
UString name = usprintf("%c%c%c%c%c%c%c%c%c%c%c%c",
moduleHeader->Name[0], moduleHeader->Name[1], moduleHeader->Name[2], moduleHeader->Name[3],
moduleHeader->Name[4], moduleHeader->Name[5], moduleHeader->Name[6], moduleHeader->Name[7],
moduleHeader->Name[8], moduleHeader->Name[9], moduleHeader->Name[10],moduleHeader->Name[11]);
UString name = usprintf("%.12s", moduleHeader->Name);
// This hash is stored reversed
// Need to reverse it back to normal
UByteArray hash((const char*)&moduleHeader->MetadataHash, sizeof(moduleHeader->MetadataHash));
UByteArray hash((const char*)&moduleHeader->MetadataHash, moduleHeader->HashSize);
std::reverse(hash.begin(), hash.end());
UString info = usprintf("Full size: %X (%u)\nType: %Xh\nHash algorithm: %Xh\nHash size: %Xh (%u)\nMetadata size: %Xh (%u)\nMetadata hash: ",
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\nHash algorithm: %Xh\nHash size: %Xh (%u)\nMetadata size: %Xh (%u)\nMetadata hash: ",
module.size(), module.size(),
moduleHeader->Type,
moduleHeader->HashAlgorithm,
moduleHeader->HashSize, moduleHeader->HashSize,
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
// Add tree otem
model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
UModelIndex extIndex = model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
if (sizeof (moduleHeader->MetadataHash) != moduleHeader->HashSize) {
msg(usprintf("%s: CPD Signed Package Info hash size is %d, expected %lu", __FUNCTION__, moduleHeader->HashSize, sizeof (moduleHeader->MetadataHash)), extIndex);
}
offset += module.size();
}
@ -5250,3 +5261,37 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
return U_SUCCESS;
}
void FfsParser::outputInfo(void) {
// Show ffsParser's messages
std::vector<std::pair<UString, UModelIndex> > messages = getMessages();
for (size_t i = 0; i < messages.size(); i++) {
std::cout << (const char *)messages[i].first.toLocal8Bit() << std::endl;
}
// Get last VTF
std::vector<std::pair<std::vector<UString>, UModelIndex > > fitTable = getFitTable();
if (fitTable.size()) {
std::cout << "---------------------------------------------------------------------------" << std::endl;
std::cout << " Address | Size | Ver | CS | Type / Info " << std::endl;
std::cout << "---------------------------------------------------------------------------" << std::endl;
for (size_t i = 0; i < fitTable.size(); i++) {
std::cout
<< (const char *)fitTable[i].first[0].toLocal8Bit() << " | "
<< (const char *)fitTable[i].first[1].toLocal8Bit() << " | "
<< (const char *)fitTable[i].first[2].toLocal8Bit() << " | "
<< (const char *)fitTable[i].first[3].toLocal8Bit() << " | "
<< (const char *)fitTable[i].first[4].toLocal8Bit() << " | "
<< (const char *)fitTable[i].first[5].toLocal8Bit() << std::endl;
}
}
// Get security info
UString secInfo = getSecurityInfo();
if (!secInfo.isEmpty()) {
std::cout << "------------------------------------------------------------------------" << std::endl;
std::cout << "Security Info" << std::endl;
std::cout << "------------------------------------------------------------------------" << std::endl;
std::cout << (const char *)secInfo.toLocal8Bit() << std::endl;
}
}

View File

@ -46,7 +46,7 @@ public:
FfsParser(TreeModel* treeModel);
~FfsParser();
// Obtain parser messages
// Obtain parser messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const;
// Clear messages
void clearMessages() { messagesVector.clear(); }
@ -63,6 +63,9 @@ public:
// Obtain offset/address difference
UINT64 getAddressDiff() { return addressDiff; }
// Output some info to stdout
void outputInfo(void);
private:
TreeModel *model;
std::vector<std::pair<UString, UModelIndex> > messagesVector;

View File

@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsreport.h"
#include "ffs.h"
#include "utility.h"
#include "uinttypes.h"
std::vector<UString> FfsReport::generate()
{
@ -62,7 +63,7 @@ USTATUS FfsReport::generateRecursive(std::vector<UString> & report, const UModel
UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16)
+ UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22)
+ offset
+ usprintf("| %08X | %08X | ", data.size(), crc)
+ usprintf("| %08" PRIXQ " | %08X | ", data.size(), crc)
+ urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString() : UString(" | ") + text)
);

View File

@ -22,7 +22,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Memory address of a pointer to FIT, 40h back from the end of flash chip
#define FIT_POINTER_OFFSET 0x40
// Entry types
// Entry types
#define FIT_TYPE_HEADER 0x00
#define FIT_TYPE_MICROCODE 0x01
#define FIT_TYPE_BIOS_AC_MODULE 0x02
@ -38,7 +38,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define FIT_MICROCODE_VERSION 0x0100
const UByteArray FIT_SIGNATURE
("\x5F\x46\x49\x54\x5F\x20\x20\x20", 8);
("\x5F\x46\x49\x54\x5F\x20\x20\x20", 8);
typedef struct FIT_ENTRY_ {
UINT64 Address;

View File

@ -64,7 +64,7 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
if (line.size() == 0 || line[0] == '#')
continue;
// GUID and name are comma-separated
// GUID and name are comma-separated
std::vector<UString> lineParts;
std::string::size_type prev = 0, curr = 0;
while ((curr = line.find(',', curr)) != std::string::npos) {
@ -103,7 +103,7 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
UString guidDatabaseLookup(const EFI_GUID & guid)
{
U_UNUSED_PARAMETER(guid);
U_UNUSED_PARAMETER(guid);
return UString();
}
#endif

View File

@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <inttypes.h>
#include <map>
#include "ffs.h"
@ -20,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "meparser.h"
#include "parsingdata.h"
#include "utility.h"
#include "uinttypes.h"
#ifdef U_ENABLE_ME_PARSING_SUPPORT
@ -138,7 +138,7 @@ USTATUS MeParser::parseFptRegion(const UByteArray & region, const UModelIndex &
UByteArray body = region.mid(header.size(), ptBodySize);
UString name = UString("FPT partition table");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nROM bypass vector: %s\nNumber of entries: %u\nHeader version: %02Xh\nEntry version: %02Xh\n"
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %Xh (%u)\nROM bypass vector: %s\nNumber of entries: %u\nHeader version: %02Xh\nEntry version: %02Xh\n"
"Header length: %02Xh\nTicks to add: %04Xh\nTokens to add: %04Xh\nUMA size: %Xh\nFlash layout: %Xh\nFITC version: %u.%u.%u.%u\nChecksum: %02Xh, ",
ptSize, ptSize,
header.size(), header.size(),
@ -173,7 +173,7 @@ USTATUS MeParser::parseFptRegion(const UByteArray & region, const UModelIndex &
// Get info
name = visibleAsciiOrHex((UINT8*)ptEntry->Name, 4);
info = usprintf("Full size: %Xh (%u)\nPartition offset: %Xh\nPartition length: %Xh\nPartition type: %02Xh",
info = usprintf("Full size: %lXh (%lu)\nPartition offset: %Xh\nPartition length: %Xh\nPartition type: %02Xh",
sizeof(FPT_HEADER_ENTRY), sizeof(FPT_HEADER_ENTRY),
ptEntry->Offset,
ptEntry->Size,
@ -276,8 +276,8 @@ make_partition_table_consistent:
if (partitions[i].type == Types::FptPartition) {
UModelIndex partitionIndex;
// Get info
name = visibleAsciiOrHex((UINT8*) partitions[i].ptEntry.Name, 4);
info = usprintf("Full size: %Xh (%u)\nPartition type: %02Xh\n",
name = visibleAsciiOrHex((UINT8*) partitions[i].ptEntry.Name, 4);
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nPartition type: %02Xh\n",
partition.size(), partition.size(),
partitions[i].ptEntry.Type);
@ -293,7 +293,7 @@ make_partition_table_consistent:
else if (partitions[i].type == Types::Padding) {
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", partition.size(), partition.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", partition.size(), partition.size());
// Add tree item
model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);
@ -318,14 +318,14 @@ USTATUS MeParser::parseIfwi16Region(const UByteArray & region, const UModelIndex
UByteArray header = region.left(ptSize);
UString name = UString("IFWI 1.6 header");
UString info = usprintf("Full size: %Xh (%u)\n"
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\n"
"Data partition offset: %Xh\nData partition size: %Xh\n"
"Boot1 partition offset: %Xh\nBoot1 partition size: %Xh\n"
"Boot2 partition offset: %Xh\nBoot2 partition size: %Xh\n"
"Boot3 partition offset: %Xh\nBoot3 partition size: %Xh\n"
"Boot4 partition offset: %Xh\nBoot4 partition size: %Xh\n"
"Boot5 partition offset: %Xh\nBoot5 partition size: %Xh\n"
"Checksum: %Xh",
"Checksum: %llXh",
header.size(), header.size(),
ifwiHeader->DataPartition.Offset, ifwiHeader->DataPartition.Size,
ifwiHeader->BootPartition[0].Offset, ifwiHeader->BootPartition[0].Size,
@ -440,7 +440,7 @@ make_partition_table_consistent:
}
// Get info
info = usprintf("Full size: %Xh (%u)\n",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\n",
partition.size(), partition.size());
// Add tree item
@ -460,7 +460,7 @@ make_partition_table_consistent:
else if (partitions[i].type == Types::Padding) {
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", partition.size(), partition.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", partition.size(), partition.size());
// Add tree item
model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);
@ -486,7 +486,7 @@ USTATUS MeParser::parseIfwi17Region(const UByteArray & region, const UModelIndex
UByteArray header = region.left(ptSize);
UString name = UString("IFWI 1.7 header");
UString info = usprintf("Full size: %Xh (%u)\n"
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\n"
"Flags: %02Xh\n"
"Reserved: %02Xh\n"
"Checksum: %Xh\n"
@ -626,7 +626,7 @@ make_partition_table_consistent:
}
// Get info
info = usprintf("Full size: %Xh (%u)\n",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\n",
partition.size(), partition.size());
// Add tree item
@ -646,7 +646,7 @@ make_partition_table_consistent:
else if (partitions[i].type == Types::Padding) {
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", partition.size(), partition.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", partition.size(), partition.size());
// Add tree item
model->addItem(partitions[i].ptEntry.Offset, Types::Padding, getPaddingType(partition), name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);

View File

@ -25,14 +25,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "sha256.h"
#ifdef U_ENABLE_ME_PARSING_SUPPORT
class MeParser
class MeParser
{
public:
// Default constructor and destructor
MeParser(TreeModel* treeModel, FfsParser* parser) : model(treeModel), ffsParser(parser) {}
~MeParser() {}
// Returns messages
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
// Clears messages
void clearMessages() { messagesVector.clear(); }
@ -53,14 +53,14 @@ private:
USTATUS parseIfwi17Region(const UByteArray & region, const UModelIndex & parent, UModelIndex & index);
};
#else
class MeParser
class MeParser
{
public:
// Default constructor and destructor
MeParser(TreeModel* treeModel, FfsParser* parser) { U_UNUSED_PARAMETER(treeModel); U_UNUSED_PARAMETER(parser); }
~MeParser() {}
// Returns messages
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return std::vector<std::pair<UString, UModelIndex> >(); }
// Clears messages
void clearMessages() {}

View File

@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UString nvarAttributesToUString(const UINT8 attributes)
{
if (attributes == 0x00 || attributes == 0xFF)
if (attributes == 0x00 || attributes == 0xFF)
return UString();
UString str;

View File

@ -147,7 +147,7 @@ typedef struct VSS_APPLE_VARIABLE_HEADER_ {
// Authenticated variable header, used for SecureBoot vars
typedef struct VSS_AUTH_VARIABLE_HEADER_ {
UINT16 StartId; // Variable start marker AA55
UINT8 State; // Variable state
UINT8 State; // Variable state
UINT8 Reserved;
UINT32 Attributes; // Variable attributes
UINT64 MonotonicCounter; // Monotonic counter against replay attack
@ -164,7 +164,7 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
#define NVRAM_VSS_VARIABLE_HEADER_VALID 0x7f // Variable has valid header
#define NVRAM_VSS_VARIABLE_ADDED 0x3f // Variable has been completely added
#define NVRAM_VSS_INTEL_VARIABLE_VALID 0xfc // Intel special variable valid
#define NVRAM_VSS_INTEL_VARIABLE_INVALID 0xf8 // Intel special variable invalid
#define NVRAM_VSS_INTEL_VARIABLE_INVALID 0xf8 // Intel special variable invalid
// VSS variable attributes
#define NVRAM_VSS_VARIABLE_NON_VOLATILE 0x00000001

View File

@ -14,11 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//TODO: relax fixed restrictions once NVRAM builder is ready
// A workaround for compilers not supporting c++11 and c11
// for using PRIX64.
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <map>
#include "nvramparser.h"
@ -27,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "nvram.h"
#include "ffs.h"
#include "fit.h"
#include "uinttypes.h"
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
@ -96,14 +92,14 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
UByteArray padding = data.mid(offset, unparsedSize);
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space
// Add tree item
model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
else {
// Nothing is parsed yet, but the file is not empty
// Nothing is parsed yet, but the file is not empty
if (!offset) {
msg(usprintf("%s: file can't be parsed as NVAR variables store", __FUNCTION__), index);
return U_SUCCESS;
@ -117,7 +113,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
UByteArray guidArea = data.right(guidAreaSize);
// Get info
name = UString("GUID store");
info = usprintf("Full size: %Xh (%u)\nGUIDs in store: %u",
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nGUIDs in store: %u",
guidArea.size(), guidArea.size(),
guidsInStore);
// Add tree item
@ -323,7 +319,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
info += usprintf("GUID index: %u\n", guidIndex);
// Add header, body and extended data info
info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
info += usprintf("Full size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")",
entryHeader->Size, entryHeader->Size,
header.size(), header.size(),
body.size(), body.size());
@ -366,9 +362,9 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// Show messages
if (msgUnknownExtDataFormat) msg(usprintf("%s: unknown extended data format", __FUNCTION__), varIndex);
if (msgExtHeaderTooLong) msg(usprintf("%s: extended header size (%Xh) is greater than body size (%Xh)", __FUNCTION__,
if (msgExtHeaderTooLong) msg(usprintf("%s: extended header size (%Xh) is greater than body size (%" PRIXQ "h)", __FUNCTION__,
extendedHeaderSize, body.size()), varIndex);
if (msgExtDataTooShort) msg(usprintf("%s: extended header size (%Xh) is too small for timestamp and hash", __FUNCTION__,
if (msgExtDataTooShort) msg(usprintf("%s: extended header size (%" PRIXQ "h) is too small for timestamp and hash", __FUNCTION__,
tail.size()), varIndex);
// Try parsing the entry data as NVAR storage if it begins with NVAR signature
@ -417,7 +413,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Get info
UByteArray padding = data.left(prevStoreOffset);
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
model->addItem(localOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -436,7 +432,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
model->addItem(localOffset + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -457,7 +453,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
// Add tree item
UModelIndex paddingIndex = model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
@ -487,14 +483,14 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
if ((UINT32)data.size() > storeOffset) {
UByteArray padding = data.mid(storeOffset);
// Add info
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
if (padding.count(emptyByte) == padding.size()) { // Free space
// Add tree item
model->addItem(localOffset + storeOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
else {
// Nothing is parsed yet, but the file is not empty
// Nothing is parsed yet, but the file is not empty
if (!storeOffset) {
msg(usprintf("%s: can't be parsed as NVRAM volume", __FUNCTION__), index);
return U_SUCCESS;
@ -548,7 +544,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
if (dataSize < sizeof(UINT32))
return U_STORES_NOT_FOUND;
// TODO: add checks for restSize
// TODO: add checks for restSize
UINT32 offset = storeOffset;
for (; offset < dataSize - sizeof(UINT32); offset++) {
const UINT32* currentPos = (const UINT32*)(volume.constData() + offset);
@ -633,7 +629,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos;
if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) {
msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", __FUNCTION__, localOffset + offset, ftw64Header->WriteQueueSize), index);
msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %llXh", __FUNCTION__, localOffset + offset, ftw64Header->WriteQueueSize), index);
continue;
}
}
@ -816,7 +812,7 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
name = UString("VSS store");
}
UString info = usprintf("Signature: %Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nUnknown: %04Xh",
UString info = usprintf("Signature: %Xh\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nFormat: %02Xh\nState: %02Xh\nUnknown: %04Xh",
vssStoreHeader->Signature,
storeSize, storeSize,
header.size(), header.size(),
@ -865,7 +861,7 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32
// Add info
UString name = UString("VSS2 store");
UString info = UString("Signature: ") + guidToUString(vssStoreHeader->Signature, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nUnknown: %04Xh",
usprintf("\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nFormat: %02Xh\nState: %02Xh\nUnknown: %04Xh",
storeSize, storeSize,
header.size(), header.size(),
body.size(), body.size(),
@ -935,7 +931,7 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
// Add info
UString name("FTW store");
UString info = UString("Signature: ") + guidToUString(ftw32BlockHeader->Signature, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh",
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %" PRIXQ "h (%" PRIuQ ")\nState: %02Xh\nHeader CRC32: %08Xh",
ftwBlockSize, ftwBlockSize,
headerSize, headerSize,
body.size(), body.size(),
@ -976,7 +972,7 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
// Add info
UString name("FDC store");
UString info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
UString info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")",
fdcStoreHeader->Size, fdcStoreHeader->Size,
header.size(), header.size(),
body.size(), body.size());
@ -1019,13 +1015,14 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
// Add info
bool isGaidStore = (fsysStoreHeader->Signature == NVRAM_APPLE_GAID_STORE_SIGNATURE);
UString name = isGaidStore ? UString("Gaid store") : UString("Fsys store");
UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nUnknown0: %02Xh\nUnknown1: %08Xh\nCRC32: %08Xh",
UString info = usprintf("Signature: %s\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nUnknown0: %02Xh\nUnknown1: %08Xh\nCRC32: %08Xh",
isGaidStore ? "Gaid" : "Fsys",
fsysStoreHeader->Size, fsysStoreHeader->Size,
header.size(), header.size(),
body.size(), body.size(),
fsysStoreHeader->Unknown0,
fsysStoreHeader->Unknown1)
fsysStoreHeader->Unknown1,
storedCrc)
+ (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
// Add tree item
@ -1064,14 +1061,14 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
// Add info
UString name("EVSA store");
UString info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nAttributes: %08Xh\nChecksum: %02Xh",
UString info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nType: %02Xh\nAttributes: %08Xh\nChecksum: %02Xh",
evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize,
header.size(), header.size(),
body.size(), body.size(),
evsaStoreHeader->Header.Type,
evsaStoreHeader->Attributes,
evsaStoreHeader->Header.Checksum) +
(evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid"));
(evsaStoreHeader->Header.Checksum != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid"));
// Add tree item
index = model->addItem(localOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
@ -1107,7 +1104,7 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
// Add info
UString name("Phoenix SCT flash map");
UString info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u",
UString info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nNumber of entries: %u",
flashMapSize, flashMapSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1146,7 +1143,7 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32
// Add info
UString name("CMDB store");
UString info = usprintf("Signature: CMDB\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
UString info = usprintf("Signature: CMDB\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")",
cmdbSize, cmdbSize,
header.size(), header.size(),
body.size(), body.size());
@ -1183,7 +1180,7 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
// Add info
UString name("SLIC pubkey");
UString info = usprintf("Type: 0h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n"
UString info = usprintf("Type: 0h\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: 0h (0)\n"
"Key type: %02Xh\nVersion: %02Xh\nAlgorithm: %08Xh\nMagic: RSA1\nBit length: %08Xh\nExponent: %08Xh",
pubkeyHeader->Size, pubkeyHeader->Size,
header.size(), header.size(),
@ -1225,7 +1222,7 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
// Add info
UString name("SLIC marker");
UString info = usprintf("Type: 1h\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\n"
UString info = usprintf("Type: 1h\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: 0h (0)\n"
"Version: %08Xh\nOEM ID: %s\nOEM table ID: %s\nWindows flag: WINDOWS\nSLIC version: %08Xh",
markerHeader->Size, markerHeader->Size,
header.size(), header.size(),
@ -1394,7 +1391,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
UINT32 variableSize = 0;
if (unparsedSize >= sizeof(VSS_VARIABLE_HEADER)
&& variableHeader->StartId == NVRAM_VSS_VARIABLE_START_ID) {
// Apple VSS variable with CRC32 of the data
// Apple VSS variable with CRC32 of the data
if (variableHeader->Attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) {
isAppleCrc32 = true;
if (unparsedSize < sizeof(VSS_APPLE_VARIABLE_HEADER)) {
@ -1486,14 +1483,14 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
// Check if the data left is a free space or a padding
UByteArray padding = data.mid(offset, unparsedSize);
// Get info
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", padding.size(), padding.size());
if (padding.count(emptyByte) == padding.size()) { // Free space
// Add tree item
model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
else { // Padding
// Nothing is parsed yet, but the store is not empty
// Nothing is parsed yet, but the store is not empty
if (!offset) {
msg(usprintf("%s: store can't be parsed as VSS store", __FUNCTION__), index);
return U_SUCCESS;
@ -1525,7 +1522,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
}
// Add info
info += usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (",
info += usprintf("Full size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1606,7 +1603,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
if (nameSize == 3 && name[0] == 'E' && name[1] == 'O' && name[2] == 'F') {
// There is no data afterward, add EOF variable and free space and return
UByteArray header = data.mid(offset, sizeof(UINT8) + nameSize);
UString info = usprintf("Full size: %Xh (%u)", header.size(), header.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", header.size(), header.size());
// Add EOF tree item
model->addItem(localOffset + offset, Types::FsysEntry, Subtypes::NormalFsysEntry, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), Fixed, index);
@ -1614,7 +1611,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
// Add free space
offset += header.size();
UByteArray body = data.mid(offset);
info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", body.size(), body.size());
// Add free space tree item
model->addItem(localOffset + offset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
@ -1631,7 +1628,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
else {
// Last variable is bad, add the rest as padding and return
UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", body.size(), body.size());
// Add padding tree item
model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
@ -1647,7 +1644,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
UByteArray body = data.mid(offset + sizeof(UINT8) + nameSize + sizeof(UINT16), dataSize);
// Add info
UString info = usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)",
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size());
@ -1707,7 +1704,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
variableSize = sizeof(EVSA_ENTRY_HEADER);
if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) {
body = data.mid(offset);
info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", body.size(), body.size());
if (body.count(emptyByte) == body.size()) { // Free space
// Add free space tree item
@ -1735,7 +1732,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY));
EFI_GUID guid = *(EFI_GUID*)body.constData();
name = guidToUString(guid);
info = UString("GUID: ") + guidToUString(guid, false) + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
info = UString("GUID: ") + guidToUString(guid, false) + usprintf("\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nType: %02Xh\nChecksum: %02Xh",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1759,7 +1756,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
name = UString::fromUtf16((const CHAR16*)body.constData());
#endif
info = UString("Name: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
info = UString("Name: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nType: %02Xh\nChecksum: %02Xh",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1788,7 +1785,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
header = data.mid(offset, headerSize);
body = data.mid(offset + headerSize, dataSize);
name = UString("Data");
info = usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
variableSize, variableSize,
headerSize, headerSize,
dataSize, dataSize,
@ -1805,7 +1802,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
// Unknown entry or free space
else {
body = data.mid(offset);
info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", body.size(), body.size());
if (body.count(emptyByte) == body.size()) { // Free space
// Add free space tree item
@ -1903,7 +1900,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
if (unparsedSize < sizeof(PHOENIX_FLASH_MAP_ENTRY)) {
// Last variable is bad, add the rest as padding and return
UByteArray body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")", body.size(), body.size());
// Add padding tree item
model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
@ -1923,7 +1920,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
// Add info
UString info = UString("Entry GUID: ") + guidToUString(entryHeader->Guid, false) +
usprintf("\nFull size: 24h (36)\nHeader size: 24h (36)\nBody size: 0h (0)\n"
"Entry type: %04Xh\nData type: %04Xh\nMemory address: %08Xh\nSize: %08Xh\nOffset: %08Xh",
"Entry type: %04Xh\nData type: %04Xh\nMemory address: %08llXh\nSize: %08Xh\nOffset: %08Xh",
entryHeader->EntryType,
entryHeader->DataType,
entryHeader->PhysicalAddress,

View File

@ -24,14 +24,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsparser.h"
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
class NvramParser
class NvramParser
{
public:
// Default constructor and destructor
NvramParser(TreeModel* treeModel, FfsParser* parser) : model(treeModel), ffsParser(parser) {}
~NvramParser() {}
// Returns messages
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
// Clears messages
void clearMessages() { messagesVector.clear(); }
@ -70,14 +70,14 @@ private:
USTATUS parseFlashMapBody(const UModelIndex & index);
};
#else
class NvramParser
class NvramParser
{
public:
// Default constructor and destructor
NvramParser(TreeModel* treeModel, FfsParser* parser) { U_UNUSED_PARAMETER(treeModel); U_UNUSED_PARAMETER(parser); }
~NvramParser() {}
// Returns messages
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return std::vector<std::pair<UString, UModelIndex> >(); }
// Clears messages
void clearMessages() {}

View File

@ -45,7 +45,7 @@ extern UString machineTypeToUString(UINT16 machineType);
#define EFI_IMAGE_FILE_MACHINE_IA64 0x0200 // Itanium
#define EFI_IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI Byte Code
#define EFI_IMAGE_FILE_MACHINE_AMD64 0x8664 // x86-64
#define EFI_IMAGE_FILE_MACHINE_AARCH64 0xaa64 // ARMv8 in 64-bit mode
#define EFI_IMAGE_FILE_MACHINE_AARCH64 0xaa64 // ARMv8 in 64-bit mode
#define EFI_IMAGE_FILE_MACHINE_RISCV32 0x5032 // RISC-V 32-bit
#define EFI_IMAGE_FILE_MACHINE_RISCV64 0x5064 // RISC-V 64-bit
#define EFI_IMAGE_FILE_MACHINE_RISCV128 0x5128 // RISC-V 128-bit

View File

@ -108,10 +108,10 @@ static void sha256_compress(struct sha256_state *md, unsigned char *buf)
W[i - 16];
}
/* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = (uint32_t)(h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]); \
t1 = (uint32_t)(Sigma0(a) + Maj(a, b, c)); \
d += t0; \
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = (uint32_t)(h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]); \
t1 = (uint32_t)(Sigma0(a) + Maj(a, b, c)); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 64; ++i) {
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);

View File

@ -14,11 +14,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h"
#include "types.h"
TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
const UString & name, const UString & text, const UString & info,
const UByteArray & header, const UByteArray & body, const UByteArray & tail,
const bool fixed, const bool compressed,
TreeItem *parent) :
TreeItem *parent) :
itemOffset(offset),
itemAction(Actions::NoAction),
itemType(type),
@ -94,8 +94,8 @@ int TreeItem::row() const
}
TreeItem* TreeItem::child(int row)
{
std::list<TreeItem*>::iterator child = childItems.begin();
std::advance(child, row);
return *child;
{
std::list<TreeItem*>::iterator child = childItems.begin();
std::advance(child, row);
return *child;
}

View File

@ -334,8 +334,8 @@ void TreeModel::setCompressed(const UModelIndex &index, const bool compressed)
emit dataChanged(index, index);
}
void TreeModel::TreeModel::setMarkingEnabled(const bool enabled)
{
void TreeModel::TreeModel::setMarkingEnabled(const bool enabled)
{
markingEnabledFlag = enabled;
emit dataChanged(UModelIndex(), UModelIndex());

View File

@ -37,7 +37,7 @@ enum ItemFixedState {
#define UModelIndex QModelIndex
#else
// Use own implementation
// Use own implementation
#include "ustring.h"
#include "ubytearray.h"
#include "basetypes.h"

View File

@ -97,14 +97,14 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
if (subtype == Subtypes::OnePadding) return UString("Empty (0xFF)");
if (subtype == Subtypes::DataPadding) return UString("Non-empty");
break;
case Types::Volume:
case Types::Volume:
if (subtype == Subtypes::UnknownVolume) return UString("Unknown");
if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2");
if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3");
if (subtype == Subtypes::NvramVolume) return UString("NVRAM");
if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode");
break;
case Types::Capsule:
case Types::Capsule:
if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed");
if (subtype == Subtypes::AptioUnsignedCapsule) return UString("Aptio unsigned");
if (subtype == Subtypes::UefiCapsule) return UString("UEFI 2.0");
@ -146,7 +146,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
if (subtype == Subtypes::IntelMicrocode) return UString("Intel");
if (subtype == Subtypes::AmdMicrocode) return UString("AMD");
break;
// ME-specific
// ME-specific
case Types::FptEntry:
if (subtype == Subtypes::ValidFptEntry) return UString("Valid");
if (subtype == Subtypes::InvalidFptEntry) return UString("Invalid");

View File

@ -181,7 +181,7 @@ namespace Subtypes {
DataFptPartition,
GlutFptPartition
};
enum CpdPartitionSubtypes {
ManifestCpdPartition = 230,
MetadataCpdPartition,

View File

@ -64,7 +64,7 @@ public:
}
UByteArray left(int32_t len) const { return d.substr(0, len); }
UByteArray right(int32_t len) const { return d.substr(d.size() - 1 - len, len); }
UByteArray right(int32_t len) const { return d.substr(d.size() - len, len); }
UByteArray mid(int32_t pos, int32_t len = -1) const { return d.substr(pos, len); }
UByteArray & operator=(const UByteArray & ba) { d = ba.d; return *this; }
@ -77,12 +77,11 @@ public:
for (int32_t i = 0; i < size(); i++) {
uint8_t low = d[i] & 0x0F;
uint8_t high = (d[i] & 0xF0) >> 4;
low += (low < 10 ? '0' : 'a');
high += (high < 10 ? '0' : 'a');
hex[2*i] = low;
hex[2*i + 1] = high;
low += (low < 10 ? '0' : 'a' - 10);
high += (high < 10 ? '0' : 'a' - 10);
hex[2*i] = high;
hex[2*i + 1] = low;
}
std::reverse(hex.begin(), hex.end());
return UByteArray(hex);
}

44
common/uinttypes.h Normal file
View File

@ -0,0 +1,44 @@
/* uinttypes.h
Copyright (c) 2021, 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.
*/
#ifndef UINTTYPES_H
#define UINTTYPES_H
// A workaround for compilers not supporting c++11 and c11
// for using PRIX64.
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#if QT_VERSION_MAJOR >= 6
# define PRIdQ __PRI_64_LENGTH_MODIFIER__ "d"
# define PRIiQ __PRI_64_LENGTH_MODIFIER__ "i"
# define PRIoQ __PRI_64_LENGTH_MODIFIER__ "o"
# define PRIuQ __PRI_64_LENGTH_MODIFIER__ "u"
# define PRIxQ __PRI_64_LENGTH_MODIFIER__ "x"
# define PRIXQ __PRI_64_LENGTH_MODIFIER__ "X"
#else
# define PRIdQ "d"
# define PRIiQ "i"
# define PRIoQ "o"
# define PRIuQ "u"
# define PRIxQ "x"
# define PRIXQ "X"
#endif
#if defined(__clang__) || defined(__GNUC__)
#define ATTRIBUTE_FORMAT_(t,f,a) __attribute__((format(t, f, a)))
#else
#define ATTRIBUTE_FORMAT_(t,f,a)
#endif
#endif // UINTTYPES_H

View File

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <stdarg.h>
#if defined(QT_CORE_LIB)
UString usprintf(const char* fmt, ...)
UString usprintf(const char* fmt, ...)
{
UString msg;
va_list vl;

View File

@ -24,8 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "bstrlib/bstrwrap.h"
#define UString CBString
#endif // QT_CORE_LIB
#include "uinttypes.h"
UString usprintf(const char* fmt, ...);
UString usprintf(const char* fmt, ...) ATTRIBUTE_FORMAT_(printf, 1, 2);
UString urepeated(char c, int len);
#endif // USTRING_H

View File

@ -95,23 +95,39 @@ UString uniqueItemName(const UModelIndex & index)
+ (subtypeString.length() ? ('_' + subtypeString) : UString())
+ '_' + name;
fixFileName(name, true);
return name;
}
// Makes the name usable as a file name
void fixFileName(UString &name, bool replaceSpaces)
{
// Replace some symbols with underscores for compatibility
const char table[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // ASCII control characters, banned in Windows, hard to work with in *nix
'/', // Banned in *nix and Windows
'<', '>', ':', '\"', '\\', '|', '?', '*', // Banned in Windows
' ' // Provides better readability
};
int nameLength = (int)name.length(); // Note: Qt uses int for whatever reason.
for (int i = 0; i < nameLength; i++) {
if (
name[i] < (char)0x20 || // ASCII control characters, banned in Windows, hard to work with in *nix
name[i] > (char)0x7f || // high ASCII characters
(replaceSpaces && name[i] == ' ') // Provides better readability
) {
name[i] = '_';
continue;
}
for (size_t j = 0; j < sizeof(table); j++) {
if (name[i] == table[j]) {
name[i] = '_';
break;
}
}
}
return name;
if (!nameLength) {
name = "_";
}
}
// Returns text representation of error code
@ -168,7 +184,7 @@ UString errorCodeToUString(USTATUS errorCode)
case U_INVALID_CAPSULE: return UString("Invalid capsule");
case U_STORES_NOT_FOUND: return UString("Stores not found");
case U_INVALID_STORE_SIZE: return UString("Invalid store size");
default: return usprintf("Unknown error %02X", errorCode);
default: return usprintf("Unknown error %02lX", errorCode);
}
}

View File

@ -29,6 +29,9 @@ UString visibleAsciiOrHex(UINT8* bytes, UINT32 length);
// Returns unique name for tree item
UString uniqueItemName(const UModelIndex & index);
// Makes the name usable as a file name
void fixFileName(UString &name, bool replaceSpaces);
// Converts error code to UString
UString errorCodeToUString(USTATUS errorCode);
@ -63,9 +66,9 @@ INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSi
// Safely dereferences misaligned pointers
template <typename T>
inline T readUnaligned(const T *v) {
T tmp;
memcpy(&tmp, v, sizeof(T));
return tmp;
T tmp;
memcpy(&tmp, v, sizeof(T));
return tmp;
}
#endif // UTILITY_H