mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-21 23:48:22 +08:00
- introduce Extract Uncompressed and Uncompressed Hex View actions for compressed items
- remove unused code to support Qt 5.5 and earlier Qt versions - remove unused section parsing code - add a check and description for section alignment quirk (compiled out for now)
This commit is contained in:
parent
cc274319bf
commit
12f40cf289
@ -35,12 +35,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
|||||||
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
findHexPattern(index.model()->index(i, index.column(), index), hexPattern, mode);
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray data;
|
UByteArray data;
|
||||||
@ -109,11 +104,7 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
|
|||||||
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
findGuidPattern(index.model()->index(i, index.column(), index), guidPattern, mode);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray data;
|
UByteArray data;
|
||||||
@ -197,11 +188,7 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa
|
|||||||
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
findTextPattern(index.model()->index(i, index.column(), index), pattern, mode, unicode, caseSensitive);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray body;
|
UByteArray body;
|
||||||
|
@ -37,18 +37,32 @@ void HexViewDialog::setFont(const QFont &font)
|
|||||||
hexView->setFont(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();
|
const TreeModel * model = (const TreeModel*)index.model();
|
||||||
|
|
||||||
// Set dialog title
|
|
||||||
UString itemName = model->name(index);
|
UString itemName = model->name(index);
|
||||||
UString itemText = model->text(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;
|
QByteArray hexdata;
|
||||||
if (bodyOnly) hexdata = model->body(index);
|
UString dialogTitle;
|
||||||
else hexdata = model->header(index) + model->body(index) + model->tail(index);
|
|
||||||
|
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);
|
hexView->setData(hexdata);
|
||||||
}
|
}
|
@ -24,11 +24,17 @@ class HexViewDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum HexViewType {
|
||||||
|
fullHexView,
|
||||||
|
bodyHexView,
|
||||||
|
uncompressedHexView
|
||||||
|
};
|
||||||
|
|
||||||
HexViewDialog(QWidget *parent = 0);
|
HexViewDialog(QWidget *parent = 0);
|
||||||
~HexViewDialog();
|
~HexViewDialog();
|
||||||
Ui::HexViewDialog* ui;
|
Ui::HexViewDialog* ui;
|
||||||
|
|
||||||
void setItem(const UModelIndex & index, bool bodyOnly);
|
void setItem(const UModelIndex & index, HexViewType dataType);
|
||||||
void setFont(const QFont &font);
|
void setFont(const QFont &font);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -43,6 +43,7 @@ markingEnabled(true)
|
|||||||
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
|
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
|
||||||
connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView()));
|
connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView()));
|
||||||
connect(ui->actionBodyHexView, SIGNAL(triggered()), this, SLOT(bodyHexView()));
|
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->actionExtract, SIGNAL(triggered()), this, SLOT(extractAsIs()));
|
||||||
connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody()));
|
connect(ui->actionExtractBody, SIGNAL(triggered()), this, SLOT(extractBody()));
|
||||||
connect(ui->actionExtractBodyUncompressed, SIGNAL(triggered()), this, SLOT(extractBodyUncompressed()));
|
connect(ui->actionExtractBodyUncompressed, SIGNAL(triggered()), this, SLOT(extractBodyUncompressed()));
|
||||||
@ -231,6 +232,7 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
|||||||
// Enable actions
|
// Enable actions
|
||||||
ui->actionHexView->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
ui->actionHexView->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
||||||
ui->actionBodyHexView->setDisabled(model->hasEmptyBody(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->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
||||||
ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry);
|
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->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
||||||
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
|
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->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
||||||
//ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
//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) ||
|
// (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);
|
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()
|
void UEFITool::search()
|
||||||
{
|
{
|
||||||
if (searchDialog->exec() != QDialog::Accepted)
|
if (searchDialog->exec() != QDialog::Accepted)
|
||||||
@ -323,7 +318,7 @@ void UEFITool::hexView()
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hexViewDialog->setItem(index, false);
|
hexViewDialog->setItem(index, HexViewDialog::HexViewType::fullHexView);
|
||||||
hexViewDialog->exec();
|
hexViewDialog->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +328,17 @@ void UEFITool::bodyHexView()
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
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();
|
hexViewDialog->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,11 +395,7 @@ void UEFITool::goToData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
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);
|
QModelIndex currentIndex = parent.model()->index(j, 0, parent);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (model->hasEmptyParsingData(currentIndex))
|
if (model->hasEmptyParsingData(currentIndex))
|
||||||
continue;
|
continue;
|
||||||
|
@ -83,6 +83,7 @@ private slots:
|
|||||||
|
|
||||||
void hexView();
|
void hexView();
|
||||||
void bodyHexView();
|
void bodyHexView();
|
||||||
|
void uncompressedHexView();
|
||||||
void goToData();
|
void goToData();
|
||||||
|
|
||||||
void extract(const UINT8 mode);
|
void extract(const UINT8 mode);
|
||||||
@ -144,8 +145,6 @@ private:
|
|||||||
const QString version;
|
const QString version;
|
||||||
bool markingEnabled;
|
bool markingEnabled;
|
||||||
|
|
||||||
bool enableExtractBodyUncompressed(const QModelIndex ¤t);
|
|
||||||
|
|
||||||
bool eventFilter(QObject* obj, QEvent* event);
|
bool eventFilter(QObject* obj, QEvent* event);
|
||||||
void dragEnterEvent(QDragEnterEvent* event);
|
void dragEnterEvent(QDragEnterEvent* event);
|
||||||
void dropEvent(QDropEvent* event);
|
void dropEvent(QDropEvent* event);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
QT += core gui
|
QT += core gui widgets
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
TARGET = UEFITool
|
TARGET = UEFITool
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
@ -351,6 +351,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
@ -401,6 +402,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
@ -421,6 +423,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
@ -445,6 +448,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
@ -482,6 +486,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionGoToData"/>
|
<addaction name="actionGoToData"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
@ -507,6 +512,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionHexView"/>
|
<addaction name="actionHexView"/>
|
||||||
<addaction name="actionBodyHexView"/>
|
<addaction name="actionBodyHexView"/>
|
||||||
|
<addaction name="actionUncompressedHexView"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
@ -845,6 +851,17 @@
|
|||||||
<string>Ctrl+Shift+D</string>
|
<string>Ctrl+Shift+D</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionUncompressedHexView">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Un&compressed hex view...</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Alt+D</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="actionLoadGuidDatabase">
|
<action name="actionLoadGuidDatabase">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load &GUID database...</string>
|
<string>Load &GUID database...</string>
|
||||||
|
@ -414,9 +414,6 @@ typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
|
|||||||
// Section2 usage indicator
|
// Section2 usage indicator
|
||||||
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
||||||
|
|
||||||
// Apple section usage indicator
|
|
||||||
#define EFI_SECTION_APPLE_USED 0x7FFF
|
|
||||||
|
|
||||||
// File section types
|
// File section types
|
||||||
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
||||||
|
|
||||||
|
@ -92,12 +92,7 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build image
|
// 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);
|
UModelIndex imageIndex = index.model()->index(0, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
UByteArray imageData;
|
UByteArray imageData;
|
||||||
|
|
||||||
// Check image type
|
// Check image type
|
||||||
@ -170,19 +165,11 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
|
|||||||
// Rebuild
|
// Rebuild
|
||||||
else if (model->action(index) == Actions::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
|
// 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));
|
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
|
// Process other regions
|
||||||
for (int i = 1; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex currentRegion = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Skip regions with Remove action
|
// Skip regions with Remove action
|
||||||
if (model->action(currentRegion) == Actions::Remove)
|
if (model->action(currentRegion) == Actions::Remove)
|
||||||
@ -282,14 +269,9 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
|
|||||||
// Build children
|
// Build children
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
USTATUS result = U_SUCCESS;
|
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);
|
UModelIndex currentChild = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
UByteArray currentData;
|
UByteArray currentData;
|
||||||
|
|
||||||
// Check child type
|
// Check child type
|
||||||
if (model->type(currentChild) == Types::Volume) {
|
if (model->type(currentChild) == Types::Volume) {
|
||||||
result = buildVolume(currentChild, currentData);
|
result = buildVolume(currentChild, currentData);
|
||||||
|
@ -39,24 +39,9 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
|
|||||||
extracted += model->body(index);
|
extracted += model->body(index);
|
||||||
}
|
}
|
||||||
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
|
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
|
||||||
name += UString("_body_unc");
|
name += UString("_body_uncompressed");
|
||||||
// Extract without header and tail, uncompressed
|
|
||||||
extracted.clear();
|
extracted.clear();
|
||||||
// There is no need to redo decompression, we can use child items
|
extracted += model->uncompressedData(index);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return U_UNKNOWN_EXTRACT_MODE;
|
return U_UNKNOWN_EXTRACT_MODE;
|
||||||
|
@ -989,11 +989,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
|||||||
|
|
||||||
// Parse bodies
|
// Parse bodies
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (model->type(current)) {
|
switch (model->type(current)) {
|
||||||
case Types::Volume:
|
case Types::Volume:
|
||||||
@ -1111,7 +1107,9 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
|||||||
// Acquire alignment
|
// Acquire alignment
|
||||||
alignment = (UINT32)(1UL << ((volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16));
|
alignment = (UINT32)(1UL << ((volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16));
|
||||||
// Check alignment
|
// 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;
|
msgUnaligned = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1561,11 +1559,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
|
|||||||
|
|
||||||
// Check for duplicate GUIDs
|
// Check for duplicate GUIDs
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Skip non-file entries and pad files
|
// Skip non-file entries and pad files
|
||||||
if (model->type(current) != Types::File || model->subtype(current) == EFI_FV_FILETYPE_PAD) {
|
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
|
// Check files after current for having an equal GUID
|
||||||
for (int j = i + 1; j < model->rowCount(index); j++) {
|
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);
|
UModelIndex another = index.model()->index(j, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Skip non-file entries
|
// Skip non-file entries
|
||||||
if (model->type(another) != Types::File) {
|
if (model->type(another) != Types::File) {
|
||||||
@ -1600,11 +1590,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
|
|||||||
|
|
||||||
// Parse bodies
|
// Parse bodies
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (model->type(current)) {
|
switch (model->type(current)) {
|
||||||
case Types::File:
|
case Types::File:
|
||||||
@ -1696,7 +1682,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
|
|||||||
msgUnalignedFile = true;
|
msgUnalignedFile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check file alignment agains volume alignment
|
// Check file alignment against volume alignment
|
||||||
bool msgFileAlignmentIsGreaterThanVolumeAlignment = false;
|
bool msgFileAlignmentIsGreaterThanVolumeAlignment = false;
|
||||||
if (!isWeakAligned && volumeAlignment < alignment) {
|
if (!isWeakAligned && volumeAlignment < alignment) {
|
||||||
msgFileAlignmentIsGreaterThanVolumeAlignment = true;
|
msgFileAlignmentIsGreaterThanVolumeAlignment = true;
|
||||||
@ -1989,12 +1975,15 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
|
|||||||
ffsVersion = pdata->ffsVersion;
|
ffsVersion = pdata->ffsVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate over sections
|
||||||
|
UINT32 sectionSize = 0;
|
||||||
while (sectionOffset < bodySize) {
|
while (sectionOffset < bodySize) {
|
||||||
// Get section size
|
// Get section size
|
||||||
UINT32 sectionSize = getSectionSize(sections, sectionOffset, ffsVersion);
|
sectionSize = getSectionSize(sections, sectionOffset, ffsVersion);
|
||||||
|
|
||||||
// Check section size
|
// Check section size to be sane
|
||||||
if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER) || sectionSize > (bodySize - sectionOffset)) {
|
if (sectionSize < sizeof(EFI_COMMON_SECTION_HEADER)
|
||||||
|
|| sectionSize > (bodySize - sectionOffset)) {
|
||||||
// Final parsing
|
// Final parsing
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
// Add padding to fill the rest of sections
|
// Add padding to fill the rest of sections
|
||||||
@ -2012,7 +2001,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
|
|||||||
// Exit from parsing loop
|
// Exit from parsing loop
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Preparsing
|
// Preliminary parsing
|
||||||
else {
|
else {
|
||||||
return U_INVALID_SECTION;
|
return U_INVALID_SECTION;
|
||||||
}
|
}
|
||||||
@ -2030,16 +2019,33 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
|
|||||||
|
|
||||||
// Move to next section
|
// Move to next section
|
||||||
sectionOffset += sectionSize;
|
sectionOffset += sectionSize;
|
||||||
|
// TODO: verify that alignment bytes are actually zero as per PI spec
|
||||||
sectionOffset = ALIGN4(sectionOffset);
|
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
|
// Parse bodies, will be skipped if insertIntoTree is not required
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (model->type(current)) {
|
switch (model->type(current)) {
|
||||||
case Types::Section:
|
case Types::Section:
|
||||||
@ -2109,20 +2115,11 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
UINT32 headerSize;
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
UINT8 type;
|
UINT32 headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
|
||||||
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);
|
|
||||||
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
|
||||||
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
|
||||||
type = sectionHeader->Type;
|
UINT8 type = sectionHeader->Type;
|
||||||
}
|
|
||||||
|
|
||||||
// Check sanity again
|
// Check sanity again
|
||||||
if ((UINT32)section.size() < headerSize) {
|
if ((UINT32)section.size() < headerSize) {
|
||||||
@ -2169,15 +2166,8 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons
|
|||||||
UINT32 uncompressedLength;
|
UINT32 uncompressedLength;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
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_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
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header 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
|
|
||||||
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1);
|
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1);
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION))
|
||||||
return U_INVALID_SECTION;
|
return U_INVALID_SECTION;
|
||||||
@ -2246,18 +2236,8 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
|
|||||||
UINT16 attributes;
|
UINT16 attributes;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
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_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
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header 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
|
|
||||||
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(section2Header + 1);
|
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))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION))
|
||||||
return U_INVALID_SECTION;
|
return U_INVALID_SECTION;
|
||||||
@ -2445,15 +2425,8 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
|
|||||||
UINT8 type;
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
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_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
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header 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
|
|
||||||
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(section2Header + 1);
|
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))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION))
|
||||||
return U_INVALID_SECTION;
|
return U_INVALID_SECTION;
|
||||||
@ -2521,15 +2494,8 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U
|
|||||||
UINT8 type;
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
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_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
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header 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
|
|
||||||
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1);
|
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1);
|
||||||
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION);
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION);
|
||||||
buildNumber = versionHeader->BuildNumber;
|
buildNumber = versionHeader->BuildNumber;
|
||||||
@ -2587,15 +2553,8 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const
|
|||||||
UINT8 type;
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
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_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
|
if (ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header 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
|
|
||||||
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1);
|
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1);
|
||||||
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION);
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION);
|
||||||
postCode = postcodeHeader->Postcode;
|
postCode = postcodeHeader->Postcode;
|
||||||
@ -2727,7 +2686,13 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
|
|||||||
model->addInfo(index, usprintf("\nLZMA dictionary size: %Xh", dictionarySize));
|
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;
|
COMPRESSED_SECTION_PARSING_DATA pdata;
|
||||||
pdata.algorithm = algorithm;
|
pdata.algorithm = algorithm;
|
||||||
pdata.dictionarySize = dictionarySize;
|
pdata.dictionarySize = dictionarySize;
|
||||||
@ -2735,9 +2700,6 @@ USTATUS FfsParser::parseCompressedSectionBody(const UModelIndex & index)
|
|||||||
pdata.uncompressedSize = uncompressedSize;
|
pdata.uncompressedSize = uncompressedSize;
|
||||||
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
||||||
|
|
||||||
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
|
||||||
model->setCompressed(index, true);
|
|
||||||
|
|
||||||
// Parse decompressed data
|
// Parse decompressed data
|
||||||
return parseSections(decompressed, index, true);
|
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());
|
info += usprintf("\nDecompressed size: %" PRIXQ "h (%" PRIuQ ")", processed.size(), processed.size());
|
||||||
}
|
}
|
||||||
// LZMA compressed section
|
// 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);
|
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed);
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
|
||||||
@ -2843,15 +2806,17 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
|
|||||||
// Add info
|
// Add info
|
||||||
model->addInfo(index, info);
|
model->addInfo(index, info);
|
||||||
|
|
||||||
// Update data
|
|
||||||
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
|
||||||
model->setCompressed(index, true);
|
|
||||||
|
|
||||||
// Set parsing data
|
// Set parsing data
|
||||||
GUIDED_SECTION_PARSING_DATA pdata;
|
GUIDED_SECTION_PARSING_DATA pdata;
|
||||||
pdata.dictionarySize = dictionarySize;
|
pdata.dictionarySize = dictionarySize;
|
||||||
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
|
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) {
|
if (!parseCurrentSection) {
|
||||||
msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index);
|
msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -3347,11 +3312,7 @@ USTATUS FfsParser::checkTeImageBase(const UModelIndex & index)
|
|||||||
|
|
||||||
// Process child items
|
// Process child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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));
|
checkTeImageBase(index.model()->index(i, 0, index));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -3388,11 +3349,7 @@ USTATUS FfsParser::addInfoRecursive(const UModelIndex & index)
|
|||||||
|
|
||||||
// Process child items
|
// Process child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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));
|
addInfoRecursive(index.model()->index(i, 0, index));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -3589,11 +3546,7 @@ USTATUS FfsParser::markProtectedRangeRecursive(const UModelIndex & index, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
markProtectedRangeRecursive(index.model()->index(i, 0, index), range);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -3897,11 +3850,7 @@ void FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & found,
|
|||||||
|
|
||||||
// Process child items
|
// Process child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
findFitRecursive(index.model()->index(i, 0, index), found, fitOffset);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (found.isValid())
|
if (found.isValid())
|
||||||
return;
|
return;
|
||||||
@ -5241,7 +5190,7 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
|
|||||||
moduleHeader->HashSize, moduleHeader->HashSize,
|
moduleHeader->HashSize, moduleHeader->HashSize,
|
||||||
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
|
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
|
||||||
// Add tree otem
|
// 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();
|
offset += module.size();
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
|
@ -69,11 +69,7 @@ USTATUS FfsReport::generateRecursive(std::vector<UString> & report, const UModel
|
|||||||
|
|
||||||
// Information on child items
|
// Information on child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
generateRecursive(report, index.model()->index(i,0,index), level + 1);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
@ -40,12 +40,7 @@ USTATUS findFileRecursive(TreeModel *model, const UModelIndex index, const UStri
|
|||||||
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
findFileRecursive(model, index.model()->index(i, index.column(), index), hexPattern, mode, files);
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray data;
|
UByteArray data;
|
||||||
|
@ -116,11 +116,7 @@ GuidDatabase guidDatabaseFromTreeRecursive(TreeModel * model, const UModelIndex
|
|||||||
return db;
|
return db;
|
||||||
|
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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));
|
GuidDatabase tmpDb = guidDatabaseFromTreeRecursive(model, index.model()->index(i, index.column(), index));
|
||||||
#endif
|
|
||||||
|
|
||||||
db.insert(tmpDb.begin(), tmpDb.end());
|
db.insert(tmpDb.begin(), tmpDb.end());
|
||||||
}
|
}
|
||||||
|
@ -226,11 +226,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
|||||||
// Search previously added entries for a link to this variable
|
// Search previously added entries for a link to this variable
|
||||||
// WARNING: O(n^2), may be very slow
|
// WARNING: O(n^2), may be very slow
|
||||||
for (int i = model->rowCount(index) - 1; i >= 0; i--) {
|
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);
|
nvarIndex = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (model->hasEmptyParsingData(nvarIndex) == false) {
|
if (model->hasEmptyParsingData(nvarIndex) == false) {
|
||||||
UByteArray nvarData = model->parsingData(nvarIndex);
|
UByteArray nvarData = model->parsingData(nvarIndex);
|
||||||
@ -503,11 +499,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
|
|||||||
|
|
||||||
// Parse bodies
|
// Parse bodies
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (model->type(current)) {
|
switch (model->type(current)) {
|
||||||
case Types::FdcStore:
|
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
|
// 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++) {
|
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);
|
UModelIndex current = index.model()->index(i, 0, index);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (model->subtype(current) == Subtypes::DataEvsaEntry) {
|
if (model->subtype(current) == Subtypes::DataEvsaEntry) {
|
||||||
UByteArray header = model->header(current);
|
UByteArray header = model->header(current);
|
||||||
|
@ -30,6 +30,7 @@ typedef struct VOLUME_PARSING_DATA_ {
|
|||||||
BOOLEAN hasExtendedHeader;
|
BOOLEAN hasExtendedHeader;
|
||||||
BOOLEAN hasAppleCrc32;
|
BOOLEAN hasAppleCrc32;
|
||||||
BOOLEAN isWeakAligned;
|
BOOLEAN isWeakAligned;
|
||||||
|
BOOLEAN requiresSectionAlignmentQuirk;
|
||||||
} VOLUME_PARSING_DATA;
|
} VOLUME_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct FILE_PARSING_DATA_ {
|
typedef struct FILE_PARSING_DATA_ {
|
||||||
|
@ -86,6 +86,10 @@ public:
|
|||||||
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
|
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
|
||||||
void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; }
|
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; }
|
UINT8 marking() const { return itemMarking; }
|
||||||
void setMarking(const UINT8 marking) { itemMarking = marking; }
|
void setMarking(const UINT8 marking) { itemMarking = marking; }
|
||||||
|
|
||||||
@ -105,6 +109,7 @@ private:
|
|||||||
bool itemFixed;
|
bool itemFixed;
|
||||||
bool itemCompressed;
|
bool itemCompressed;
|
||||||
UByteArray itemParsingData;
|
UByteArray itemParsingData;
|
||||||
|
UByteArray itemUncompressedData;
|
||||||
TreeItem* parentItem;
|
TreeItem* parentItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -460,6 +460,34 @@ void TreeModel::setParsingData(const UModelIndex &index, const UByteArray &data)
|
|||||||
emit dataChanged(this->index(0, 0), index);
|
emit dataChanged(this->index(0, 0), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UByteArray TreeModel::uncompressedData(const UModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return UByteArray();
|
||||||
|
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
return item->uncompressedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TreeModel::hasEmptyUncompressedData(const UModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
return item->hasEmptyUncompressedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeModel::setUncompressedData(const UModelIndex &index, const UByteArray &data)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
item->setUncompressedData(data);
|
||||||
|
emit dataChanged(this->index(0, 0), index);
|
||||||
|
}
|
||||||
|
|
||||||
UModelIndex TreeModel::addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
|
UModelIndex TreeModel::addItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
|
||||||
const UString & name, const UString & text, const UString & info,
|
const UString & name, const UString & text, const UString & info,
|
||||||
const UByteArray & header, const UByteArray & body, const UByteArray & tail,
|
const UByteArray & header, const UByteArray & body, const UByteArray & tail,
|
||||||
@ -559,11 +587,7 @@ UModelIndex TreeModel::findByBase(UINT32 base) const
|
|||||||
goDeeper:
|
goDeeper:
|
||||||
int n = rowCount(parentIndex);
|
int n = rowCount(parentIndex);
|
||||||
for (int i = 0; i < n; i++) {
|
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);
|
UModelIndex currentIndex = parentIndex.model()->index(i, 0, parentIndex);
|
||||||
#endif
|
|
||||||
|
|
||||||
UINT32 currentBase = this->base(currentIndex);
|
UINT32 currentBase = this->base(currentIndex);
|
||||||
UINT32 fullSize = (UINT32)(header(currentIndex).size() + body(currentIndex).size() + tail(currentIndex).size());
|
UINT32 fullSize = (UINT32)(header(currentIndex).size() + body(currentIndex).size() + tail(currentIndex).size());
|
||||||
|
@ -170,6 +170,10 @@ public:
|
|||||||
bool compressed(const UModelIndex &index) const;
|
bool compressed(const UModelIndex &index) const;
|
||||||
void setCompressed(const UModelIndex &index, const bool compressed);
|
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;
|
UINT8 marking(const UModelIndex &index) const;
|
||||||
void setMarking(const UModelIndex &index, const UINT8 marking);
|
void setMarking(const UModelIndex &index, const UINT8 marking);
|
||||||
|
|
||||||
|
@ -20,11 +20,7 @@ UString usprintf(const char* fmt, ...)
|
|||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, fmt);
|
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);
|
msg = msg.vasprintf(fmt, vl);
|
||||||
#endif
|
|
||||||
|
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
return msg;
|
return msg;
|
||||||
|
Loading…
Reference in New Issue
Block a user