diff --git a/UEFITool/ffsfinder.cpp b/UEFITool/ffsfinder.cpp
index 044c007..b84589b 100644
--- a/UEFITool/ffsfinder.cpp
+++ b/UEFITool/ffsfinder.cpp
@@ -35,12 +35,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- findHexPattern(index.child(i, index.column()), hexPattern, mode);
-#else
findHexPattern(index.model()->index(i, index.column(), index), hexPattern, mode);
-#endif
-
}
UByteArray data;
@@ -109,11 +104,7 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- findGuidPattern(index.child(i, index.column()), guidPattern, mode);
-#else
findGuidPattern(index.model()->index(i, index.column(), index), guidPattern, mode);
-#endif
}
UByteArray data;
@@ -197,11 +188,7 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive);
-#else
findTextPattern(index.model()->index(i, index.column(), index), pattern, mode, unicode, caseSensitive);
-#endif
}
UByteArray body;
diff --git a/UEFITool/hexviewdialog.cpp b/UEFITool/hexviewdialog.cpp
index 11e6ed1..227162a 100644
--- a/UEFITool/hexviewdialog.cpp
+++ b/UEFITool/hexviewdialog.cpp
@@ -37,18 +37,32 @@ void HexViewDialog::setFont(const QFont &font)
hexView->setFont(font);
}
-void HexViewDialog::setItem(const UModelIndex & index, bool bodyOnly)
+void HexViewDialog::setItem(const UModelIndex & index, HexViewType type)
{
const TreeModel * model = (const TreeModel*)index.model();
-
- // Set dialog title
UString itemName = model->name(index);
UString itemText = model->text(index);
- setWindowTitle(UString("Hex view: ") + (itemText.isEmpty() ? itemName : itemName + " | " + itemText));
- // Set hex data
+ // Set hex data and dialog title
QByteArray hexdata;
- if (bodyOnly) hexdata = model->body(index);
- else hexdata = model->header(index) + model->body(index) + model->tail(index);
+ UString dialogTitle;
+
+ switch (type) {
+ case fullHexView:
+ dialogTitle = UString("Hex view: ");
+ hexdata = model->header(index) + model->body(index) + model->tail(index);
+ break;
+ case bodyHexView:
+ dialogTitle = UString("Body hex view: ");
+ hexdata = model->body(index);
+ break;
+ case uncompressedHexView:
+ dialogTitle = UString("Uncompressed hex view: ");
+ hexdata = model->uncompressedData(index);
+ break;
+ }
+
+ dialogTitle += itemText.isEmpty() ? itemName : itemName + " | " + itemText;
+ setWindowTitle(dialogTitle);
hexView->setData(hexdata);
-}
\ No newline at end of file
+}
diff --git a/UEFITool/hexviewdialog.h b/UEFITool/hexviewdialog.h
index ad7d29b..1aa53e1 100644
--- a/UEFITool/hexviewdialog.h
+++ b/UEFITool/hexviewdialog.h
@@ -24,13 +24,19 @@ class HexViewDialog : public QDialog
Q_OBJECT
public:
+ enum HexViewType {
+ fullHexView,
+ bodyHexView,
+ uncompressedHexView
+ };
+
HexViewDialog(QWidget *parent = 0);
~HexViewDialog();
Ui::HexViewDialog* ui;
- void setItem(const UModelIndex & index, bool bodyOnly);
+ void setItem(const UModelIndex & index, HexViewType dataType);
void setFont(const QFont &font);
-
+
private:
QHexEdit * hexView;
};
diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp
index 8e20288..e93a5db 100644
--- a/UEFITool/uefitool.cpp
+++ b/UEFITool/uefitool.cpp
@@ -43,6 +43,7 @@ markingEnabled(true)
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView()));
connect(ui->actionBodyHexView, SIGNAL(triggered()), this, SLOT(bodyHexView()));
+ connect(ui->actionUncompressedHexView, SIGNAL(triggered()), this, SLOT(uncompressedHexView()));
connect(ui->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs()));
connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody()));
connect(ui->actionExtractBodyUncompressed, SIGNAL(triggered()), this, SLOT(extractBodyUncompressed()));
@@ -231,6 +232,7 @@ void UEFITool::populateUi(const QModelIndex ¤t)
// Enable actions
ui->actionHexView->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
ui->actionBodyHexView->setDisabled(model->hasEmptyBody(current));
+ ui->actionUncompressedHexView->setDisabled(model->hasEmptyUncompressedData(current));
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry);
@@ -240,7 +242,7 @@ void UEFITool::populateUi(const QModelIndex ¤t)
//ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
- ui->actionExtractBodyUncompressed->setEnabled(enableExtractBodyUncompressed(current));
+ ui->actionExtractBodyUncompressed->setDisabled(model->hasEmptyUncompressedData(current));
//ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
//ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
// (type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
@@ -253,13 +255,6 @@ void UEFITool::populateUi(const QModelIndex ¤t)
ui->menuMessageActions->setEnabled(false);
}
-bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t)
-{
- // TODO: rewrite based on model->compressed()
- U_UNUSED_PARAMETER(current);
- return false;
-}
-
void UEFITool::search()
{
if (searchDialog->exec() != QDialog::Accepted)
@@ -323,7 +318,7 @@ void UEFITool::hexView()
if (!index.isValid())
return;
- hexViewDialog->setItem(index, false);
+ hexViewDialog->setItem(index, HexViewDialog::HexViewType::fullHexView);
hexViewDialog->exec();
}
@@ -333,7 +328,17 @@ void UEFITool::bodyHexView()
if (!index.isValid())
return;
- hexViewDialog->setItem(index, true);
+ hexViewDialog->setItem(index, HexViewDialog::HexViewType::bodyHexView);
+ hexViewDialog->exec();
+}
+
+void UEFITool::uncompressedHexView()
+{
+ QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
+ if (!index.isValid())
+ return;
+
+ hexViewDialog->setItem(index, HexViewDialog::HexViewType::uncompressedHexView);
hexViewDialog->exec();
}
@@ -390,11 +395,7 @@ void UEFITool::goToData()
}
for (int j = i + 1; j < model->rowCount(parent); j++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- QModelIndex currentIndex = parent.child(j, 0);
-#else
QModelIndex currentIndex = parent.model()->index(j, 0, parent);
-#endif
if (model->hasEmptyParsingData(currentIndex))
continue;
diff --git a/UEFITool/uefitool.h b/UEFITool/uefitool.h
index 3fa3a07..d758ba6 100644
--- a/UEFITool/uefitool.h
+++ b/UEFITool/uefitool.h
@@ -83,6 +83,7 @@ private slots:
void hexView();
void bodyHexView();
+ void uncompressedHexView();
void goToData();
void extract(const UINT8 mode);
@@ -144,8 +145,6 @@ private:
const QString version;
bool markingEnabled;
- bool enableExtractBodyUncompressed(const QModelIndex ¤t);
-
bool eventFilter(QObject* obj, QEvent* event);
void dragEnterEvent(QDragEnterEvent* event);
void dropEvent(QDropEvent* event);
diff --git a/UEFITool/uefitool.pro b/UEFITool/uefitool.pro
index 6a90bb4..728b416 100644
--- a/UEFITool/uefitool.pro
+++ b/UEFITool/uefitool.pro
@@ -1,5 +1,4 @@
-QT += core gui
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+QT += core gui widgets
TARGET = UEFITool
TEMPLATE = app
diff --git a/UEFITool/uefitool.ui b/UEFITool/uefitool.ui
index 63113c3..51b6248 100644
--- a/UEFITool/uefitool.ui
+++ b/UEFITool/uefitool.ui
@@ -351,6 +351,7 @@
+
@@ -401,6 +402,7 @@
+
@@ -421,6 +423,7 @@
+
@@ -445,6 +448,7 @@
+
@@ -482,6 +486,7 @@
+
@@ -507,6 +512,7 @@
+
@@ -845,6 +851,17 @@
Ctrl+Shift+D
+
+
+ false
+
+
+ Un&compressed hex view...
+
+
+ Ctrl+Alt+D
+
+
Load &GUID database...
diff --git a/common/ffs.h b/common/ffs.h
index 4add301..5c3987a 100644
--- a/common/ffs.h
+++ b/common/ffs.h
@@ -414,9 +414,6 @@ typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
// Section2 usage indicator
#define EFI_SECTION2_IS_USED 0xFFFFFF
-// Apple section usage indicator
-#define EFI_SECTION_APPLE_USED 0x7FFF
-
// File section types
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
diff --git a/common/ffsbuilder.cpp b/common/ffsbuilder.cpp
index db114b7..6160532 100644
--- a/common/ffsbuilder.cpp
+++ b/common/ffsbuilder.cpp
@@ -92,12 +92,7 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
}
// Build image
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex imageIndex = index.child(0, 0);
-#else
UModelIndex imageIndex = index.model()->index(0, 0, index);
-#endif
-
UByteArray imageData;
// Check image type
@@ -170,19 +165,11 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
// Rebuild
else if (model->action(index) == Actions::Rebuild) {
// First child will always be descriptor for this type of image, and it's read only for now
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- intelImage = model->header(index.child(0, 0)) + model->body(index.child(0, 0)) + model->tail(index.child(0, 0));
-#else
intelImage = model->header(index.model()->index(0, 0, index)) + model->body(index.model()->index(0, 0, index)) + model->tail(index.model()->index(0, 0, index));
-#endif
// Process other regions
for (int i = 1; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex currentRegion = index.child(i, 0);
-#else
UModelIndex currentRegion = index.model()->index(i, 0, index);
-#endif
// Skip regions with Remove action
if (model->action(currentRegion) == Actions::Remove)
@@ -282,14 +269,9 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
// Build children
for (int i = 0; i < model->rowCount(index); i++) {
USTATUS result = U_SUCCESS;
-
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex currentChild = index.child(i, 0);
-#else
UModelIndex currentChild = index.model()->index(i, 0, index);
-#endif
-
UByteArray currentData;
+
// Check child type
if (model->type(currentChild) == Types::Volume) {
result = buildVolume(currentChild, currentData);
diff --git a/common/ffsops.cpp b/common/ffsops.cpp
index a2eb09f..f1b2093 100644
--- a/common/ffsops.cpp
+++ b/common/ffsops.cpp
@@ -39,24 +39,9 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
extracted += model->body(index);
}
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
- name += UString("_body_unc");
- // Extract without header and tail, uncompressed
+ name += UString("_body_uncompressed");
extracted.clear();
- // There is no need to redo decompression, we can use child items
- for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex childIndex = index.child(i, 0);
-#else
- UModelIndex childIndex = index.model()->index(i, 0, index);
-#endif
-
- // Ensure 4-byte alignment of current section
- extracted += UByteArray(ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size(), '\x00');
- // Add current section header, body and tail
- extracted += model->header(childIndex);
- extracted += model->body(childIndex);
- extracted += model->tail(childIndex);
- }
+ extracted += model->uncompressedData(index);
}
else
return U_UNKNOWN_EXTRACT_MODE;
diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp
index 0e7dae8..7d2c227 100644
--- a/common/ffsparser.cpp
+++ b/common/ffsparser.cpp
@@ -989,11 +989,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Parse bodies
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
switch (model->type(current)) {
case Types::Volume:
@@ -1111,7 +1107,9 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
// Acquire alignment
alignment = (UINT32)(1UL << ((volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16));
// Check alignment
- if (!isUnknown && !model->compressed(parent) && ((model->base(parent) + localOffset - imageBase) % alignment))
+ if (!isUnknown
+ && !model->compressed(parent) // Alignment checks don't really make sense for compressed volumes because they have to be extracted into memory, and by that point it's unlikely that the module doing such extraction will misalign them
+ && ((model->base(parent) + localOffset - imageBase) % alignment) != 0) // Explicit "is not zero" here for better code readability
msgUnaligned = true;
}
else {
@@ -1561,11 +1559,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
// Check for duplicate GUIDs
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
// Skip non-file entries and pad files
if (model->type(current) != Types::File || model->subtype(current) == EFI_FV_FILETYPE_PAD) {
@@ -1577,11 +1571,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
// Check files after current for having an equal GUID
for (int j = i + 1; j < model->rowCount(index); j++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex another = index.child(j, 0);
-#else
UModelIndex another = index.model()->index(j, 0, index);
-#endif
// Skip non-file entries
if (model->type(another) != Types::File) {
@@ -1600,11 +1590,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
// Parse bodies
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
switch (model->type(current)) {
case Types::File:
@@ -1696,7 +1682,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
msgUnalignedFile = true;
}
- // Check file alignment agains volume alignment
+ // Check file alignment against volume alignment
bool msgFileAlignmentIsGreaterThanVolumeAlignment = false;
if (!isWeakAligned && volumeAlignment < alignment) {
msgFileAlignmentIsGreaterThanVolumeAlignment = true;
@@ -1989,12 +1975,15 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
ffsVersion = pdata->ffsVersion;
}
+ // Iterate over sections
+ UINT32 sectionSize = 0;
while (sectionOffset < bodySize) {
// Get section size
- UINT32 sectionSize = getSectionSize(sections, sectionOffset, ffsVersion);
+ sectionSize = getSectionSize(sections, sectionOffset, ffsVersion);
- // Check section size
- if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER) || sectionSize > (bodySize - sectionOffset)) {
+ // Check section size to be sane
+ if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER)
+ || sectionSize > (bodySize - sectionOffset)) {
// Final parsing
if (insertIntoTree) {
// Add padding to fill the rest of sections
@@ -2012,7 +2001,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
// Exit from parsing loop
break;
}
- // Preparsing
+ // Preliminary parsing
else {
return U_INVALID_SECTION;
}
@@ -2030,16 +2019,33 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
// Move to next section
sectionOffset += sectionSize;
+ // TODO: verify that alignment bytes are actually zero as per PI spec
sectionOffset = ALIGN4(sectionOffset);
}
+#if 0 // Do not enable this in production for now, as it needs further investigation.
+ // The PI spec requires sections to be aligned by 4 byte boundary with bytes that are all exactly zeroes
+ // Some images interpret "must be aligned by 4" as "every section needs to be padded for sectionSize to be divisible by 4".
+ // Detecting this case can be done by checking for the very last section to have sectionSize not divisible by 4, while the total bodySize is.
+ // However, such detection for a single file is unreliable because in 1/4 random cases the last section will be divisible by 4.
+ // We also know that either PEI core or DXE core is entity that does file and section parsing,
+ // so every single file in the volume should behave consistently.
+ // This makes the probability of unsuccessful detection here to be 1/(4^numFilesInVolume),
+ // which is low enough for real images out there.
+ // It should also be noted that enabling this section alignment quirk for an image that doesn't require it
+ // will not make the image unbootable, but will waste some space and possibly require to move some files around
+ if (sectionOffset == bodySize) {
+ // We are now at the very end of the file body, and sectionSize is the size of the last section
+ if ((sectionSize % 4 != 0) // sectionSize of the very last section is not divisible by 4
+ && (bodySize % 4 == 0)) { // yet bodySize is, meaning that there are indeed some padding bytes added after the last section
+ msg(usprintf("%s: section alignment quirk found", __FUNCTION__), index);
+ }
+ }
+#endif
+
// Parse bodies, will be skipped if insertIntoTree is not required
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
switch (model->type(current)) {
case Types::Section:
@@ -2109,21 +2115,12 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI
}
// Obtain header fields
- UINT32 headerSize;
- UINT8 type;
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) {
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE);
- type = appleHeader->Type;
- }
- else {
- const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
+ const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
+ UINT32 headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
- type = sectionHeader->Type;
- }
-
+ UINT8 type = sectionHeader->Type;
+
// Check sanity again
if ((UINT32)section.size() < headerSize) {
return U_INVALID_SECTION;
@@ -2169,15 +2166,8 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons
UINT32 uncompressedLength;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
- const EFI_COMPRESSION_SECTION_APPLE* appleSectionHeader = (const EFI_COMPRESSION_SECTION_APPLE*)(appleHeader + 1);
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_COMPRESSION_SECTION_APPLE);
- compressionType = (UINT8)appleSectionHeader->CompressionType;
- uncompressedLength = appleSectionHeader->UncompressedLength;
- }
- else if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
+ if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION))
return U_INVALID_SECTION;
@@ -2246,18 +2236,8 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
UINT16 attributes;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
- const EFI_GUID_DEFINED_SECTION_APPLE* appleSectionHeader = (const EFI_GUID_DEFINED_SECTION_APPLE*)(appleHeader + 1);
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_GUID_DEFINED_SECTION_APPLE);
- if ((UINT32)section.size() < headerSize)
- return U_INVALID_SECTION;
- guid = appleSectionHeader->SectionDefinitionGuid;
- dataOffset = appleSectionHeader->DataOffset;
- attributes = appleSectionHeader->Attributes;
- }
- else if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
+ if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION))
return U_INVALID_SECTION;
@@ -2445,15 +2425,8 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
- const EFI_FREEFORM_SUBTYPE_GUID_SECTION* appleSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(appleHeader + 1);
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
- guid = appleSectionHeader->SubTypeGuid;
- type = appleHeader->Type;
- }
- else if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
+ if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION))
return U_INVALID_SECTION;
@@ -2521,15 +2494,8 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
- const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(appleHeader + 1);
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_VERSION_SECTION);
- buildNumber = versionHeader->BuildNumber;
- type = appleHeader->Type;
- }
- else if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
+ if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION);
buildNumber = versionHeader->BuildNumber;
@@ -2587,15 +2553,8 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
- const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
-
- if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
- const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(appleHeader + 1);
- headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(POSTCODE_SECTION);
- postCode = postcodeHeader->Postcode;
- type = appleHeader->Type;
- }
- else if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
+
+ if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION);
postCode = postcodeHeader->Postcode;
@@ -2727,17 +2686,20 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
model->addInfo(index, usprintf("\nLZMA dictionary size: %Xh", dictionarySize));
}
- // Update parsing data
+ // Set compression data
+ if (algorithm != COMPRESSION_ALGORITHM_NONE) {
+ model->setUncompressedData(index, decompressed);
+ model->setCompressed(index, true);
+ }
+
+ // Set parsing data
COMPRESSED_SECTION_PARSING_DATA pdata;
pdata.algorithm = algorithm;
pdata.dictionarySize = dictionarySize;
pdata.compressionType = compressionType;
pdata.uncompressedSize = uncompressedSize;
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
-
- if (algorithm != COMPRESSION_ALGORITHM_NONE)
- model->setCompressed(index, true);
-
+
// Parse decompressed data
return parseSections(decompressed, index, true);
}
@@ -2793,7 +2755,8 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
}
// LZMA compressed section
- else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMA_HP) {
+ else if (baGuid == EFI_GUIDED_SECTION_LZMA
+ || baGuid == EFI_GUIDED_SECTION_LZMA_HP) {
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed);
if (result) {
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
@@ -2843,15 +2806,17 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
// Add info
model->addInfo(index, info);
- // Update data
- if (algorithm != COMPRESSION_ALGORITHM_NONE)
- model->setCompressed(index, true);
-
// Set parsing data
GUIDED_SECTION_PARSING_DATA pdata;
pdata.dictionarySize = dictionarySize;
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
+ // Set compression data
+ if (algorithm != COMPRESSION_ALGORITHM_NONE) {
+ model->setUncompressedData(index, processed);
+ model->setCompressed(index, true);
+ }
+
if (!parseCurrentSection) {
msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index);
return U_SUCCESS;
@@ -3347,11 +3312,7 @@ USTATUS FfsParser::checkTeImageBase(const UModelIndex & index)
// Process child items
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- checkTeImageBase(index.child(i, 0));
-#else
checkTeImageBase(index.model()->index(i, 0, index));
-#endif
}
return U_SUCCESS;
@@ -3388,11 +3349,7 @@ USTATUS FfsParser::addInfoRecursive(const UModelIndex & index)
// Process child items
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- addInfoRecursive(index.child(i, 0));
-#else
addInfoRecursive(index.model()->index(i, 0, index));
-#endif
}
return U_SUCCESS;
@@ -3589,11 +3546,7 @@ USTATUS FfsParser::markProtectedRangeRecursive(const UModelIndex & index, const
}
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- markProtectedRangeRecursive(index.child(i, 0), range);
-#else
markProtectedRangeRecursive(index.model()->index(i, 0, index), range);
-#endif
}
return U_SUCCESS;
@@ -3897,11 +3850,7 @@ void FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & found,
// Process child items
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- findFitRecursive(index.child(i, 0), found, fitOffset);
-#else
findFitRecursive(index.model()->index(i, 0, index), found, fitOffset);
-#endif
if (found.isValid())
return;
@@ -5241,7 +5190,7 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
moduleHeader->HashSize, moduleHeader->HashSize,
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
// Add tree otem
- UModelIndex extIndex = model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
+ model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
offset += module.size();
}
else break;
diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp
index b1926c4..c19b532 100644
--- a/common/ffsreport.cpp
+++ b/common/ffsreport.cpp
@@ -69,11 +69,7 @@ USTATUS FfsReport::generateRecursive(std::vector & report, const UModel
// Information on child items
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- generateRecursive(report, index.child(i,0), level + 1);
-#else
generateRecursive(report, index.model()->index(i,0,index), level + 1);
-#endif
}
return U_SUCCESS;
diff --git a/common/ffsutils.cpp b/common/ffsutils.cpp
index c9c67a7..733bfcc 100644
--- a/common/ffsutils.cpp
+++ b/common/ffsutils.cpp
@@ -40,12 +40,7 @@ USTATUS findFileRecursive(TreeModel *model, const UModelIndex index, const UStri
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- findFileRecursive(model, index.child(i, index.column()), hexPattern, mode, files);
-#else
findFileRecursive(model, index.model()->index(i, index.column(), index), hexPattern, mode, files);
-#endif
-
}
UByteArray data;
diff --git a/common/guiddatabase.cpp b/common/guiddatabase.cpp
index 84bbf76..862b24d 100644
--- a/common/guiddatabase.cpp
+++ b/common/guiddatabase.cpp
@@ -116,11 +116,7 @@ GuidDatabase guidDatabaseFromTreeRecursive(TreeModel * model, const UModelIndex
return db;
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- GuidDatabase tmpDb = guidDatabaseFromTreeRecursive(model, index.child(i, index.column()));
-#else
GuidDatabase tmpDb = guidDatabaseFromTreeRecursive(model, index.model()->index(i, index.column(), index));
-#endif
db.insert(tmpDb.begin(), tmpDb.end());
}
diff --git a/common/nvramparser.cpp b/common/nvramparser.cpp
index e4ae149..709109d 100755
--- a/common/nvramparser.cpp
+++ b/common/nvramparser.cpp
@@ -226,11 +226,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// Search previously added entries for a link to this variable
// WARNING: O(n^2), may be very slow
for (int i = model->rowCount(index) - 1; i >= 0; i--) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- nvarIndex = index.child(i, 0);
-#else
nvarIndex = index.model()->index(i, 0, index);
-#endif
if (model->hasEmptyParsingData(nvarIndex) == false) {
UByteArray nvarData = model->parsingData(nvarIndex);
@@ -503,11 +499,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Parse bodies
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
switch (model->type(current)) {
case Types::FdcStore:
@@ -1828,11 +1820,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
// Reparse all data variables to detect invalid ones and assign name and test to valid ones
for (int i = 0; i < model->rowCount(index); i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex current = index.child(i, 0);
-#else
UModelIndex current = index.model()->index(i, 0, index);
-#endif
if (model->subtype(current) == Subtypes::DataEvsaEntry) {
UByteArray header = model->header(current);
diff --git a/common/parsingdata.h b/common/parsingdata.h
index 9179171..e920fc8 100644
--- a/common/parsingdata.h
+++ b/common/parsingdata.h
@@ -30,6 +30,7 @@ typedef struct VOLUME_PARSING_DATA_ {
BOOLEAN hasExtendedHeader;
BOOLEAN hasAppleCrc32;
BOOLEAN isWeakAligned;
+ BOOLEAN requiresSectionAlignmentQuirk;
} VOLUME_PARSING_DATA;
typedef struct FILE_PARSING_DATA_ {
diff --git a/common/treeitem.h b/common/treeitem.h
index 87d75af..0baf3e1 100644
--- a/common/treeitem.h
+++ b/common/treeitem.h
@@ -86,6 +86,10 @@ public:
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; }
+ UByteArray uncompressedData() const { return itemUncompressedData; };
+ bool hasEmptyUncompressedData() const { return itemUncompressedData.isEmpty(); }
+ void setUncompressedData(const UByteArray & ucdata) { itemUncompressedData = ucdata; }
+
UINT8 marking() const { return itemMarking; }
void setMarking(const UINT8 marking) { itemMarking = marking; }
@@ -105,6 +109,7 @@ private:
bool itemFixed;
bool itemCompressed;
UByteArray itemParsingData;
+ UByteArray itemUncompressedData;
TreeItem* parentItem;
};
diff --git a/common/treemodel.cpp b/common/treemodel.cpp
index d4f938e..d7cb47d 100644
--- a/common/treemodel.cpp
+++ b/common/treemodel.cpp
@@ -460,6 +460,34 @@ void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data)
emit dataChanged(this->index(0, 0), index);
}
+UByteArray TreeModel::uncompressedData(const UModelIndex &index) const
+{
+ if (!index.isValid())
+ return UByteArray();
+
+ TreeItem *item = static_cast(index.internalPointer());
+ return item->uncompressedData();
+}
+
+bool TreeModel::hasEmptyUncompressedData(const UModelIndex &index) const
+{
+ if (!index.isValid())
+ return true;
+
+ TreeItem *item = static_cast(index.internalPointer());
+ return item->hasEmptyUncompressedData();
+}
+
+void TreeModel::setUncompressedData(const UModelIndex &index, const UByteArray &data)
+{
+ if (!index.isValid())
+ return;
+
+ TreeItem *item = static_cast(index.internalPointer());
+ item->setUncompressedData(data);
+ emit dataChanged(this->index(0, 0), index);
+}
+
UModelIndex TreeModel::addItem(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,
@@ -559,11 +587,7 @@ UModelIndex TreeModel::findByBase(UINT32 base) const
goDeeper:
int n = rowCount(parentIndex);
for (int i = 0; i < n; i++) {
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- UModelIndex currentIndex = parentIndex.child(i, 0);
-#else
UModelIndex currentIndex = parentIndex.model()->index(i, 0, parentIndex);
-#endif
UINT32 currentBase = this->base(currentIndex);
UINT32 fullSize = (UINT32)(header(currentIndex).size() + body(currentIndex).size() + tail(currentIndex).size());
diff --git a/common/treemodel.h b/common/treemodel.h
index 296e37f..d5fe023 100644
--- a/common/treemodel.h
+++ b/common/treemodel.h
@@ -169,7 +169,11 @@ public:
bool compressed(const UModelIndex &index) const;
void setCompressed(const UModelIndex &index, const bool compressed);
-
+
+ UByteArray uncompressedData(const UModelIndex &index) const;
+ bool hasEmptyUncompressedData(const UModelIndex &index) const;
+ void setUncompressedData(const UModelIndex &index, const UByteArray &ucdata);
+
UINT8 marking(const UModelIndex &index) const;
void setMarking(const UModelIndex &index, const UINT8 marking);
diff --git a/common/ustring.cpp b/common/ustring.cpp
index 5823e01..a6efd7f 100644
--- a/common/ustring.cpp
+++ b/common/ustring.cpp
@@ -20,11 +20,7 @@ UString usprintf(const char* fmt, ...)
va_list vl;
va_start(vl, fmt);
-#if ((QT_VERSION_MAJOR == 5) && (QT_VERSION_MINOR < 6)) || (QT_VERSION_MAJOR < 5)
- msg.vsprintf(fmt, vl);
-#else
msg = msg.vasprintf(fmt, vl);
-#endif
va_end(vl);
return msg;