NE A21: deQtization begins

- added FfsBuilder code and UI, but reconstruction routines for volumes,
files and sections are still not ready
- FfsOps moved to common
- QVector and QPair aren't used anymore, replaces with std::vector and
std::pair
- common classes are now independent from QObject
- next step is to replace QString with CBString from bstrlib
This commit is contained in:
Nikolaj Schlej 2016-03-01 08:20:44 +01:00
parent b7ec76e091
commit 2024c1898b
21 changed files with 729 additions and 658 deletions

View File

@ -13,8 +13,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsfinder.h" #include "ffsfinder.h"
FfsFinder::FfsFinder(const TreeModel* treeModel, QObject *parent) FfsFinder::FfsFinder(const TreeModel* treeModel)
: QObject(parent), model(treeModel) : model(treeModel)
{ {
} }
@ -24,10 +24,10 @@ FfsFinder::~FfsFinder()
void FfsFinder::msg(const QString & message, const QModelIndex & index) void FfsFinder::msg(const QString & message, const QModelIndex & index)
{ {
messagesVector.push_back(QPair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
} }
QVector<QPair<QString, QModelIndex> > FfsFinder::getMessages() const std::vector<std::pair<QString, QModelIndex> > FfsFinder::getMessages() const
{ {
return messagesVector; return messagesVector;
} }
@ -73,11 +73,11 @@ STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & h
INT32 offset = regexp.indexIn(hexBody); INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) { while (offset >= 0) {
if (offset % 2 == 0) { if (offset % 2 == 0) {
msg(tr("Hex pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h") msg(QObject::tr("Hex pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
.arg(QString(hexPattern)) .arg(QString(hexPattern))
.arg(hexBody.mid(offset, hexPattern.length()).toUpper()) .arg(hexBody.mid(offset, hexPattern.length()).toUpper())
.arg(model->name(index)) .arg(model->name(index))
.arg(mode == SEARCH_MODE_BODY ? tr("body") : tr("header")) .arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2), .hexarg(offset / 2),
index); index);
} }
@ -142,11 +142,11 @@ STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray &
INT32 offset = regexp.indexIn(hexBody); INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) { while (offset >= 0) {
if (offset % 2 == 0) { if (offset % 2 == 0) {
msg(tr("GUID pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h") msg(QObject::tr("GUID pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
.arg(QString(guidPattern)) .arg(QString(guidPattern))
.arg(hexBody.mid(offset, hexPattern.length()).toUpper()) .arg(hexBody.mid(offset, hexPattern.length()).toUpper())
.arg(model->name(index)) .arg(model->name(index))
.arg(mode == SEARCH_MODE_BODY ? tr("body") : tr("header")) .arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2), .hexarg(offset / 2),
index); index);
} }
@ -180,7 +180,7 @@ STATUS FfsFinder::findTextPattern(const QModelIndex & index, const QString & pat
int offset = -1; int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) { while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
msg(tr("%1 text \"%2\" found in %3 at offset %4h") msg(QObject::tr("%1 text \"%2\" found in %3 at offset %4h")
.arg(unicode ? "Unicode" : "ASCII") .arg(unicode ? "Unicode" : "ASCII")
.arg(pattern) .arg(pattern)
.arg(model->name(index)) .arg(model->name(index))

View File

@ -14,26 +14,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __FFSFINDER_H__ #ifndef __FFSFINDER_H__
#define __FFSFINDER_H__ #define __FFSFINDER_H__
#include <vector>
#include <QObject> #include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
#include <QModelIndex> #include <QModelIndex>
#include <QPair>
#include <QRegExp> #include <QRegExp>
#include <QVector>
#include "../common/basetypes.h" #include "../common/basetypes.h"
#include "../common/treemodel.h" #include "../common/treemodel.h"
class FfsFinder : public QObject class FfsFinder
{ {
Q_OBJECT
public: public:
explicit FfsFinder(const TreeModel * treeModel, QObject *parent = 0); explicit FfsFinder(const TreeModel * treeModel);
~FfsFinder(); ~FfsFinder();
QVector<QPair<QString, QModelIndex> > getMessages() const; std::vector<std::pair<QString, QModelIndex> > getMessages() const;
void clearMessages(); void clearMessages();
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode); STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode);
@ -42,10 +40,9 @@ public:
private: private:
const TreeModel* model; const TreeModel* model;
QVector<QPair<QString, QModelIndex> > messagesVector; std::vector<std::pair<QString, QModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()); void msg(const QString & message, const QModelIndex &index = QModelIndex());
}; };
#endif #endif

View File

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("0.30.0_alpha20")) version(tr("0.30.0_alpha21"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -29,6 +29,7 @@ version(tr("0.30.0_alpha20"))
fitParser = NULL; fitParser = NULL;
ffsFinder = NULL; ffsFinder = NULL;
ffsOps = NULL; ffsOps = NULL;
ffsBuilder = NULL;
// Set window title // Set window title
this->setWindowTitle(tr("UEFITool %1").arg(version)); this->setWindowTitle(tr("UEFITool %1").arg(version));
@ -91,6 +92,7 @@ UEFITool::~UEFITool()
delete ffsFinder; delete ffsFinder;
delete fitParser; delete fitParser;
delete ffsParser; delete ffsParser;
delete ffsBuilder;
delete model; delete model;
delete searchDialog; delete searchDialog;
delete ui; delete ui;
@ -110,7 +112,7 @@ void UEFITool::init()
ui->fitTableWidget->setRowCount(0); ui->fitTableWidget->setRowCount(0);
ui->fitTableWidget->setColumnCount(0); ui->fitTableWidget->setColumnCount(0);
ui->infoEdit->clear(); ui->infoEdit->clear();
ui->messagesTabWidget->setTabEnabled(2, false); ui->messagesTabWidget->setTabEnabled(1, false);
// Set window title // Set window title
this->setWindowTitle(tr("UEFITool %1").arg(version)); this->setWindowTitle(tr("UEFITool %1").arg(version));
@ -157,7 +159,7 @@ void UEFITool::populateUi(const QModelIndex &current)
return; return;
UINT8 type = model->type(current); UINT8 type = model->type(current);
//UINT8 subtype = model->subtype(current); UINT8 subtype = model->subtype(current);
// Set info text // Set info text
ui->infoEdit->setPlainText(model->info(current)); ui->infoEdit->setPlainText(model->info(current));
@ -173,6 +175,11 @@ void UEFITool::populateUi(const QModelIndex &current)
// Enable actions // Enable actions
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current)); ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
// Disable rebuild for now
//ui->actionRebuild->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
//ui->actionReplace->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
//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->setEnabled(enableExtractBodyUncompressed(current));
@ -196,7 +203,8 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current)
if (model->subtype(current) == EFI_SECTION_COMPRESSION && if (model->subtype(current) == EFI_SECTION_COMPRESSION &&
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE && pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE &&
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNKNOWN) { //Compressed section pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNKNOWN &&
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNDECIDED) { //Compressed section
return true; return true;
} }
else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) { else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) {
@ -261,30 +269,6 @@ void UEFITool::search()
} }
} }
void UEFITool::rebuild()
{
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
UINT8 result = ffsEngine->rebuild(index);
if (result == ERR_SUCCESS)
ui->actionSaveImageFile->setEnabled(true);*/
}
void UEFITool::remove()
{
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
UINT8 result = ffsEngine->remove(index);
if (result == ERR_SUCCESS)
ui->actionSaveImageFile->setEnabled(true);*/
}
void UEFITool::insert(const UINT8 mode) void UEFITool::insert(const UINT8 mode)
{ {
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); /*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
@ -366,59 +350,62 @@ void UEFITool::replaceBody()
void UEFITool::replace(const UINT8 mode) void UEFITool::replace(const UINT8 mode)
{ {
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;
QString path; QString path;
if (model->type(index) == Types::Region) { if (model->type(index) == Types::Region) {
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select region file to replace selected object"), currentDir, "Region files (*.rgn *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select region file to replace %1").arg(model->name(index)), currentDir, "Region files (*.rgn *.bin);;All files (*)");
} }
else else
return; return;
} }
else if (model->type(index) == Types::Volume) { else if (model->type(index) == Types::Volume) {
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected object"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected volume"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace body"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace the body of selected volume"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
} }
else else
return; return;
} }
else if (model->type(index) == Types::File) { else if (model->type(index) == Types::File) {
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace selected object"), currentDir, "FFS files (*.ffs *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
currentDir, "FFS files (*.ffs *.bin);;All files (*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
currentDir, "Raw files (*.raw *.bin);;All files (*)");
else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced
//!TODO: handle non-empty pad files //!TODO: handle non-empty pad files
return; return;
else else
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
} }
else else
return; return;
} }
else if (model->type(index) == Types::Section) { else if (model->type(index) == Types::Section) {
if (mode == REPLACE_MODE_AS_IS) { if (mode == REPLACE_MODE_AS_IS) {
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sct *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected section"), currentDir, "Section files (*.sct *.bin);;All files (*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace body"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace the body of selected section"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"), currentDir, "Volume files (*.vol *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace the body of selected section"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_RAW) else if (model->subtype(index) == EFI_SECTION_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"), currentDir, "Raw files (*.raw *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of selected section"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC) else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC)
path = QFileDialog::getOpenFileName(this, tr("Select EFI executable file to replace body"), currentDir, "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select EFI executable file to replace the body of selected section"), currentDir, "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)");
else else
path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"), currentDir, "Binary files (*.bin);;All files (*)"); path = QFileDialog::getOpenFileName(this, tr("Select file to replace the body of selected section"), currentDir, "Binary files (*.bin);;All files (*)");
} }
else else
return; return;
@ -431,7 +418,7 @@ void UEFITool::replace(const UINT8 mode)
QFileInfo fileInfo = QFileInfo(path); QFileInfo fileInfo = QFileInfo(path);
if (!fileInfo.exists()) { if (!fileInfo.exists()) {
ui->statusBar->showMessage(tr("Please select existing file")); ui->statusBar->showMessage(tr("Please select an existing file"));
return; return;
} }
@ -446,12 +433,12 @@ void UEFITool::replace(const UINT8 mode)
QByteArray buffer = inputFile.readAll(); QByteArray buffer = inputFile.readAll();
inputFile.close(); inputFile.close();
UINT8 result = ffsEngine->replace(index, buffer, mode); UINT8 result = ffsOps->replace(index, buffer, mode);
if (result) { if (result) {
QMessageBox::critical(this, tr("Replacing failed"), errorMessage(result), QMessageBox::Ok); QMessageBox::critical(this, tr("Replacing failed"), errorCodeToQString(result), QMessageBox::Ok);
return; return;
} }
ui->actionSaveImageFile->setEnabled(true);*/ ui->actionSaveImageFile->setEnabled(true);
} }
void UEFITool::extractAsIs() void UEFITool::extractAsIs()
@ -563,6 +550,26 @@ void UEFITool::extract(const UINT8 mode)
outputFile.close(); outputFile.close();
} }
void UEFITool::rebuild()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
if (ERR_SUCCESS == ffsOps->rebuild(index))
ui->actionSaveImageFile->setEnabled(true);
}
void UEFITool::remove()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
if (ERR_SUCCESS == ffsOps->remove(index))
ui->actionSaveImageFile->setEnabled(true);
}
void UEFITool::about() void UEFITool::about()
{ {
QMessageBox::about(this, tr("About UEFITool"), tr( QMessageBox::about(this, tr("About UEFITool"), tr(
@ -588,33 +595,35 @@ void UEFITool::exit()
void UEFITool::saveImageFile() void UEFITool::saveImageFile()
{ {
/*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi *.dec);;All files (*)"); QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)");
if (path.isEmpty()) if (path.isEmpty())
return; return;
QByteArray reconstructed; QByteArray reconstructed;
UINT8 result = ffsEngine->reconstructImageFile(reconstructed); // Create ffsBuilder
showMessages(); if (!ffsBuilder)
delete ffsBuilder;
ffsBuilder = new FfsBuilder(model);
STATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
showBuilderMessages();
if (result) { if (result) {
QMessageBox::critical(this, tr("Image reconstruction failed"), errorMessage(result), QMessageBox::Ok); QMessageBox::critical(this, tr("Image build failed"), errorCodeToQString(result), QMessageBox::Ok);
return; return;
} }
QFile outputFile; QFile outputFile;
outputFile.setFileName(path); outputFile.setFileName(path);
if (!outputFile.open(QFile::WriteOnly)) { if (!outputFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("Image reconstruction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok); QMessageBox::critical(this, tr("Image build failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok);
return; return;
} }
outputFile.resize(0); outputFile.resize(0);
outputFile.write(reconstructed); outputFile.write(reconstructed);
outputFile.close(); outputFile.close();
if (QMessageBox::information(this, tr("Image reconstruction successful"), tr("Open reconstructed file?"), QMessageBox::Yes, QMessageBox::No) if (QMessageBox::Yes == QMessageBox::information(this, tr("Image build successful"), tr("Open the resulting file?"), QMessageBox::Yes, QMessageBox::No))
== QMessageBox::Yes) openImageFile(path);
openImageFile(path);*/
} }
void UEFITool::openImageFile() void UEFITool::openImageFile()
@ -692,10 +701,12 @@ void UEFITool::copyMessage()
clipboard->clear(); clipboard->clear();
if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text()); clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 1) // Search tab else if (ui->messagesTabWidget->currentIndex() == 1) // FIT tab
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 2) // FIT tab
clipboard->setText(ui->fitMessagesListWidget->currentItem()->text()); clipboard->setText(ui->fitMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 3) // Builder tab
clipboard->setText(ui->builderMessagesListWidget->currentItem()->text());
} }
void UEFITool::copyAllMessages() void UEFITool::copyAllMessages()
@ -707,14 +718,19 @@ void UEFITool::copyAllMessages()
text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
else if (ui->messagesTabWidget->currentIndex() == 1) { // Search tab else if (ui->messagesTabWidget->currentIndex() == 1) { // FIT tab
for (INT32 i = 0; i < ui->fitMessagesListWidget->count(); i++)
text.append(ui->fitMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text);
}
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++) for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++)
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
else if (ui->messagesTabWidget->currentIndex() == 2) { // FIT tab else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab
for (INT32 i = 0; i < ui->fitMessagesListWidget->count(); i++) for (INT32 i = 0; i < ui->builderMessagesListWidget->count(); i++)
text.append(ui->fitMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->builderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
} }
@ -728,17 +744,22 @@ void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
void UEFITool::clearMessages() void UEFITool::clearMessages()
{ {
if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab
ffsParser->clearMessages(); if (ffsParser) ffsParser->clearMessages();
ui->parserMessagesListWidget->clear(); ui->parserMessagesListWidget->clear();
} }
else if (ui->messagesTabWidget->currentIndex() == 1) { // Search tab else if (ui->messagesTabWidget->currentIndex() == 1) { // FIT tab
ffsFinder->clearMessages(); if (fitParser) fitParser->clearMessages();
ui->finderMessagesListWidget->clear();
}
else if (ui->messagesTabWidget->currentIndex() == 2) { // FIT tab
fitParser->clearMessages();
ui->fitMessagesListWidget->clear(); ui->fitMessagesListWidget->clear();
} }
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
if (ffsFinder) ffsFinder->clearMessages();
ui->finderMessagesListWidget->clear();
}
else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab
if (ffsBuilder) ffsBuilder->clearMessages();
ui->builderMessagesListWidget->clear();
}
ui->actionMessagesCopy->setEnabled(false); ui->actionMessagesCopy->setEnabled(false);
ui->actionMessagesCopyAll->setEnabled(false); ui->actionMessagesCopyAll->setEnabled(false);
} }
@ -761,8 +782,8 @@ void UEFITool::showParserMessages()
if (!ffsParser) if (!ffsParser)
return; return;
QVector<QPair<QString, QModelIndex> > messages = ffsParser->getMessages(); std::vector<std::pair<QString, QModelIndex> > messages = ffsParser->getMessages();
QPair<QString, QModelIndex> msg; std::pair<QString, QModelIndex> msg;
foreach (msg, messages) { foreach (msg, messages) {
ui->parserMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second)); ui->parserMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
} }
@ -771,37 +792,53 @@ void UEFITool::showParserMessages()
ui->parserMessagesListWidget->scrollToBottom(); ui->parserMessagesListWidget->scrollToBottom();
} }
void UEFITool::showFinderMessages()
{
ui->finderMessagesListWidget->clear();
if (!ffsParser)
return;
QVector<QPair<QString, QModelIndex> > messages = ffsFinder->getMessages();
QPair<QString, QModelIndex> msg;
foreach (msg, messages) {
ui->finderMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
}
ui->messagesTabWidget->setCurrentIndex(1);
ui->finderMessagesListWidget->scrollToBottom();
}
void UEFITool::showFitMessages() void UEFITool::showFitMessages()
{ {
ui->fitMessagesListWidget->clear(); ui->fitMessagesListWidget->clear();
if (!fitParser) if (!fitParser)
return; return;
QVector<QPair<QString, QModelIndex> > messages = fitParser->getMessages(); std::vector<std::pair<QString, QModelIndex> > messages = fitParser->getMessages();
QPair<QString, QModelIndex> msg; std::pair<QString, QModelIndex> msg;
foreach(msg, messages) { foreach (msg, messages) {
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second)); ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
} }
ui->fitMessagesListWidget->scrollToBottom(); ui->fitMessagesListWidget->scrollToBottom();
} }
void UEFITool::showFinderMessages()
{
ui->finderMessagesListWidget->clear();
if (!ffsParser)
return;
std::vector<std::pair<QString, QModelIndex> > messages = ffsFinder->getMessages();
std::pair<QString, QModelIndex> msg;
foreach (msg, messages) {
ui->finderMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
}
ui->messagesTabWidget->setCurrentIndex(2);
ui->finderMessagesListWidget->scrollToBottom();
}
void UEFITool::showBuilderMessages()
{
ui->builderMessagesListWidget->clear();
if (!ffsBuilder)
return;
std::vector<std::pair<QString, QModelIndex> > messages = ffsBuilder->getMessages();
std::pair<QString, QModelIndex> msg;
foreach (msg, messages) {
ui->builderMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
}
ui->messagesTabWidget->setCurrentIndex(3);
ui->builderMessagesListWidget->scrollToBottom();
}
void UEFITool::scrollTreeView(QListWidgetItem* item) void UEFITool::scrollTreeView(QListWidgetItem* item)
{ {
MessageListItem* messageItem = static_cast<MessageListItem*>(item); MessageListItem* messageItem = static_cast<MessageListItem*>(item);
@ -889,12 +926,12 @@ void UEFITool::writeSettings()
void UEFITool::showFitTable() void UEFITool::showFitTable()
{ {
QVector<QVector<QString> > fitTable = fitParser->getFitTable(); std::vector<std::vector<QString> > fitTable = fitParser->getFitTable();
if (fitTable.isEmpty()) { if (fitTable.empty()) {
return; return;
} }
// Enable FIT tab // Enable FIT tab
ui->messagesTabWidget->setTabEnabled(2, true); ui->messagesTabWidget->setTabEnabled(1, true);
// Set up the FIT table // Set up the FIT table
ui->fitTableWidget->clear(); ui->fitTableWidget->clear();
@ -907,7 +944,7 @@ void UEFITool::showFitTable()
ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true); ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true);
// Add all data to the table widget // Add all data to the table widget
for (INT32 i = 0; i < fitTable.size(); i++) { for (size_t i = 0; i < fitTable.size(); i++) {
for (UINT8 j = 0; j < 5; j++) { for (UINT8 j = 0; j < 5; j++) {
ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j])); ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j]));
} }
@ -915,5 +952,5 @@ void UEFITool::showFitTable()
ui->fitTableWidget->resizeColumnsToContents(); ui->fitTableWidget->resizeColumnsToContents();
ui->fitTableWidget->resizeRowsToContents(); ui->fitTableWidget->resizeRowsToContents();
ui->messagesTabWidget->setCurrentIndex(2); ui->messagesTabWidget->setCurrentIndex(1);
} }

View File

@ -39,10 +39,12 @@
#include "../common/ffs.h" #include "../common/ffs.h"
#include "../common/ffsparser.h" #include "../common/ffsparser.h"
#include "../common/fitparser.h" #include "../common/fitparser.h"
#include "../common/ffsops.h"
#include "../common/ffsbuilder.h"
#include "searchdialog.h" #include "searchdialog.h"
#include "messagelistitem.h" #include "messagelistitem.h"
#include "ffsfinder.h" #include "ffsfinder.h"
#include "ffsops.h"
namespace Ui { namespace Ui {
class UEFITool; class UEFITool;
@ -105,6 +107,7 @@ private:
FitParser* fitParser; FitParser* fitParser;
FfsFinder* ffsFinder; FfsFinder* ffsFinder;
FfsOperations* ffsOps; FfsOperations* ffsOps;
FfsBuilder* ffsBuilder;
SearchDialog* searchDialog; SearchDialog* searchDialog;
QClipboard* clipboard; QClipboard* clipboard;
QString currentDir; QString currentDir;
@ -121,6 +124,7 @@ private:
void showFinderMessages(); void showFinderMessages();
void showFitMessages(); void showFitMessages();
void showFitTable(); void showFitTable();
void showBuilderMessages();
}; };
#endif #endif

View File

@ -10,7 +10,7 @@ SOURCES += uefitool_main.cpp \
messagelistitem.cpp \ messagelistitem.cpp \
guidlineedit.cpp \ guidlineedit.cpp \
ffsfinder.cpp \ ffsfinder.cpp \
ffsops.cpp \ ../common/ffsops.cpp \
../common/types.cpp \ ../common/types.cpp \
../common/descriptor.cpp \ ../common/descriptor.cpp \
../common/ffs.cpp \ ../common/ffs.cpp \
@ -35,7 +35,7 @@ HEADERS += uefitool.h \
messagelistitem.h \ messagelistitem.h \
guidlineedit.h \ guidlineedit.h \
ffsfinder.h \ ffsfinder.h \
ffsops.h \ ../common/ffsops.h \
../common/basetypes.h \ ../common/basetypes.h \
../common/descriptor.h \ ../common/descriptor.h \
../common/gbe.h \ ../common/gbe.h \

View File

@ -29,7 +29,7 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_1">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -58,7 +58,7 @@
<property name="title"> <property name="title">
<string>Structure</string> <string>Structure</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -105,7 +105,7 @@
<property name="title"> <property name="title">
<string>Information</string> <string>Information</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -148,7 +148,7 @@
<attribute name="title"> <attribute name="title">
<string>Parser</string> <string>Parser</string>
</attribute> </attribute>
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -173,40 +173,11 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="finderTab">
<attribute name="title">
<string>Search</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QListWidget" name="finderMessagesListWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="fitTab"> <widget class="QWidget" name="fitTab">
<attribute name="title"> <attribute name="title">
<string>FIT</string> <string>FIT</string>
</attribute> </attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -237,6 +208,64 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="finderTab">
<attribute name="title">
<string>Search</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QListWidget" name="finderMessagesListWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="builderTab">
<attribute name="title">
<string>Builder</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QListWidget" name="builderMessagesListWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</widget> </widget>
</item> </item>
@ -294,6 +323,8 @@
</property> </property>
<addaction name="actionExtract"/> <addaction name="actionExtract"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionRebuild"/>
<addaction name="separator"/>
<addaction name="actionReplace"/> <addaction name="actionReplace"/>
</widget> </widget>
<widget class="QMenu" name="menuPaddingActions"> <widget class="QMenu" name="menuPaddingActions">

View File

@ -72,13 +72,14 @@ typedef UINT8 STATUS;
#define ERR_UNKNOWN_COMPRESSION_TYPE 26 #define ERR_UNKNOWN_COMPRESSION_TYPE 26
#define ERR_DEPEX_PARSE_FAILED 27 #define ERR_DEPEX_PARSE_FAILED 27
#define ERR_UNKNOWN_EXTRACT_MODE 28 #define ERR_UNKNOWN_EXTRACT_MODE 28
#define ERR_UNKNOWN_IMAGE_TYPE 29 #define ERR_UNKNOWN_REPLACE_MODE 29
#define ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 30 #define ERR_UNKNOWN_IMAGE_TYPE 30
#define ERR_UNKNOWN_RELOCATION_TYPE 31 #define ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE 31
#define ERR_DIR_ALREADY_EXIST 32 #define ERR_UNKNOWN_RELOCATION_TYPE 32
#define ERR_DIR_CREATE 33 #define ERR_DIR_ALREADY_EXIST 33
#define ERR_TRUNCATED_IMAGE 34 #define ERR_DIR_CREATE 34
#define ERR_INVALID_CAPSULE 35 #define ERR_TRUNCATED_IMAGE 35
#define ERR_INVALID_CAPSULE 36
#define ERR_NOT_IMPLEMENTED 0xFF #define ERR_NOT_IMPLEMENTED 0xFF
// UDK porting definitions // UDK porting definitions

View File

@ -10,7 +10,6 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include <QObject>
#include "descriptor.h" #include "descriptor.h"
// Calculate address of data structure addressed by descriptor address format // Calculate address of data structure addressed by descriptor address format

View File

@ -13,7 +13,6 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __DESCRIPTOR_H__ #ifndef __DESCRIPTOR_H__
#define __DESCRIPTOR_H__ #define __DESCRIPTOR_H__
#include <QString>
#include "basetypes.h" #include "basetypes.h"
// Make sure we use right packing rules // Make sure we use right packing rules

View File

@ -13,19 +13,19 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <QObject> #include <QObject>
#include "ffs.h" #include "ffs.h"
const QVector<QByteArray> FFSv2Volumes = const std::vector<QByteArray> FFSv2Volumes({
QVector<QByteArray>() EFI_FIRMWARE_FILE_SYSTEM_GUID,
<< EFI_FIRMWARE_FILE_SYSTEM_GUID EFI_FIRMWARE_FILE_SYSTEM2_GUID,
<< EFI_FIRMWARE_FILE_SYSTEM2_GUID EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID,
<< EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID,
<< EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID EFI_INTEL_FILE_SYSTEM_GUID,
<< EFI_INTEL_FILE_SYSTEM_GUID EFI_INTEL_FILE_SYSTEM2_GUID,
<< EFI_INTEL_FILE_SYSTEM2_GUID EFI_SONY_FILE_SYSTEM_GUID
<< EFI_SONY_FILE_SYSTEM_GUID; });
const QVector<QByteArray> FFSv3Volumes = const std::vector<QByteArray> FFSv3Volumes({
QVector<QByteArray>() EFI_FIRMWARE_FILE_SYSTEM3_GUID
<< EFI_FIRMWARE_FILE_SYSTEM3_GUID; });
const UINT8 ffsAlignmentTable[] = const UINT8 ffsAlignmentTable[] =
{ 0, 4, 7, 9, 10, 12, 15, 16 }; { 0, 4, 7, 9, 10, 12, 15, 16 };

View File

@ -15,7 +15,6 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
#include <QVector>
#include "basetypes.h" #include "basetypes.h"
// C++ functions // C++ functions
@ -138,13 +137,13 @@ const QByteArray EFI_SONY_FILE_SYSTEM_GUID
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1 // 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
// Vector of volume GUIDs with FFSv2-compatible files // Vector of volume GUIDs with FFSv2-compatible files
extern const QVector<QByteArray> FFSv2Volumes; extern const std::vector<QByteArray> FFSv2Volumes;
const QByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4dca-BD6F-1E9689E7349A const QByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4dca-BD6F-1E9689E7349A
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16); ("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
// Vector of volume GUIDs with FFSv3-compatible files // Vector of volume GUIDs with FFSv3-compatible files
extern const QVector<QByteArray> FFSv3Volumes; extern const std::vector<QByteArray> FFSv3Volumes;
// Firmware volume signature // Firmware volume signature
const QByteArray EFI_FV_SIGNATURE("_FVH", 4); const QByteArray EFI_FV_SIGNATURE("_FVH", 4);

View File

@ -12,8 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include "ffsbuilder.h" #include "ffsbuilder.h"
FfsBuilder::FfsBuilder(const TreeModel* treeModel, QObject *parent) FfsBuilder::FfsBuilder(const TreeModel* treeModel)
: QObject(parent), model(treeModel) : model(treeModel)
{ {
} }
@ -23,10 +23,10 @@ FfsBuilder::~FfsBuilder()
void FfsBuilder::msg(const QString & message, const QModelIndex & index) void FfsBuilder::msg(const QString & message, const QModelIndex & index)
{ {
messagesVector.push_back(QPair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
} }
QVector<QPair<QString, QModelIndex> > FfsBuilder::getMessages() const std::vector<std::pair<QString, QModelIndex> > FfsBuilder::getMessages() const
{ {
return messagesVector; return messagesVector;
} }
@ -47,6 +47,27 @@ STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased)
return ERR_SUCCESS; return ERR_SUCCESS;
} }
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
{
// Sanity check
if (!root.isValid())
return ERR_INVALID_PARAMETER;
if (model->type(root) == Types::Capsule) {
return buildCapsule(root, image);
}
else if (model->type(root) == Types::Image) {
if (model->subtype(root) == Subtypes::IntelImage) {
return buildIntelImage(root, image);
}
else if (model->subtype(root) == Subtypes::IntelImage) {
return buildRawArea(root, image);
}
}
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule) STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
{ {
// Sanity check // Sanity check
@ -69,7 +90,7 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
// Right now there is only one capsule image element supported // Right now there is only one capsule image element supported
if (model->rowCount(index) != 1) { if (model->rowCount(index) != 1) {
msg(tr("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index); msg(QObject::tr("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
// Use original item data // Use original item data
capsule = model->header(index).append(model->body(index)); capsule = model->header(index).append(model->body(index));
return ERR_SUCCESS; return ERR_SUCCESS;
@ -82,21 +103,27 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
// Check image type // Check image type
if (model->type(imageIndex) == Types::Image) { if (model->type(imageIndex) == Types::Image) {
STATUS result; STATUS result;
if (model->subtype(imageIndex) == Subtypes::IntelImage) if (model->subtype(imageIndex) == Subtypes::IntelImage) {
result = buildIntelImage(imageIndex, imageData); result = buildIntelImage(imageIndex, imageData);
else }
else if (model->subtype(imageIndex) == Subtypes::UefiImage) {
result = buildRawArea(imageIndex, imageData); result = buildRawArea(imageIndex, imageData);
}
else {
msg(QObject::tr("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
}
// Check build result // Check build result
if (result) { if (result) {
msg(tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToQString(result)), imageIndex); msg(QObject::tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToQString(result)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex)); capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
} }
else else
capsule.append(imageData); capsule.append(imageData);
} }
else { else {
msg(tr("buildCapsule: unexpected child item of type \"%1\" can't be processed, original item data is used").arg(itemTypeToQString(model->type(imageIndex))), imageIndex); msg(QObject::tr("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex)); capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
} }
@ -104,12 +131,12 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
UINT32 newSize = capsule.size(); UINT32 newSize = capsule.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)") msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)") msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
@ -122,7 +149,7 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -138,22 +165,17 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
return ERR_SUCCESS; return ERR_SUCCESS;
} }
// Other supported actions // Rebuild
else if (model->action(index) == Actions::Rebuild) { else if (model->action(index) == Actions::Rebuild) {
intelImage.clear(); intelImage.clear();
// First child will always be descriptor for this type of image, and it's read only // First child will always be descriptor for this type of image, and it's read only
QByteArray descriptor = model->header(index.child(0, 0)).append(model->body(index.child(0, 0))); intelImage.append(model->header(index.child(0, 0)).append(model->body(index.child(0, 0))));
// Other regions can be in different order, GbE, PDR and EC may be skipped
QByteArray gbe;
QByteArray me;
QByteArray bios;
QByteArray pdr;
QByteArray ec;
QByteArray padding;
// Process other regions
for (int i = 1; i < model->rowCount(index); i++) { for (int i = 1; i < model->rowCount(index); i++) {
QModelIndex currentRegion = index.child(i, 0); QModelIndex currentRegion = index.child(i, 0);
// Skip regions with Remove action // Skip regions with Remove action
if (model->action(currentRegion) == Actions::Remove) if (model->action(currentRegion) == Actions::Remove)
continue; continue;
@ -161,89 +183,53 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
// Check item type to be either region or padding // Check item type to be either region or padding
UINT8 type = model->type(currentRegion); UINT8 type = model->type(currentRegion);
if (type == Types::Padding) { if (type == Types::Padding) {
if (!padding.isEmpty()) { // Add padding as is
msg(tr("buildIntelImage: more than one padding found during image rebuild, the latest one is used"), index); intelImage.append(model->header(currentRegion).append(model->body(currentRegion)));
}
padding = model->header(currentRegion).append(model->body(currentRegion));
continue; continue;
} }
// Check region subtype // Check region subtype
STATUS result; STATUS result;
QByteArray region;
UINT8 regionType = model->subtype(currentRegion); UINT8 regionType = model->subtype(currentRegion);
switch (regionType) { switch (regionType) {
case Subtypes::GbeRegion:
if (!gbe.isEmpty()) {
msg(tr("buildIntelImage: more than one GbE region found during image rebuild, the latest one is used"), index);
}
result = buildGbeRegion(currentRegion, gbe);
if (result) {
msg(tr("buildIntelImage: building of GbE region failed with error \"%1\", original item data is used").arg(errorCodeToQString(result)), currentRegion);
gbe = model->header(currentRegion).append(model->body(currentRegion));
}
break;
case Subtypes::MeRegion:
if (!me.isEmpty()) {
msg(tr("buildIntelImage: more than one ME region found during image rebuild, the latest one is used"), index);
}
result = buildMeRegion(currentRegion, me);
if (result) {
msg(tr("buildIntelImage: building of ME region failed with error \"%1\", original item data is used").arg(errorCodeToQString(result)), currentRegion);
me = model->header(currentRegion).append(model->body(currentRegion));
}
break;
case Subtypes::BiosRegion: case Subtypes::BiosRegion:
if (!bios.isEmpty()) {
msg(tr("buildIntelImage: more than one BIOS region found during image rebuild, the latest one is used"), index);
}
result = buildRawArea(currentRegion, bios);
if (result) {
msg(tr("buildIntelImage: building of BIOS region failed with error \"%1\", original item data is used").arg(errorCodeToQString(result)), currentRegion);
bios = model->header(currentRegion).append(model->body(currentRegion));
}
break;
case Subtypes::PdrRegion: case Subtypes::PdrRegion:
if (!pdr.isEmpty()) { result = buildRawArea(currentRegion, region);
msg(tr("buildIntelImage: more than one PDR region found during image rebuild, the latest one is used"), index);
}
result = buildPdrRegion(currentRegion, pdr);
if (result) { if (result) {
msg(tr("buildIntelImage: building of PDR region failed with error \"%1\", original item data is used").arg(errorCodeToQString(result)), currentRegion); msg(QObject::tr("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
pdr = model->header(currentRegion).append(model->body(currentRegion)); region = model->header(currentRegion).append(model->body(currentRegion));
} }
break; break;
case Subtypes::GbeRegion:
case Subtypes::MeRegion:
case Subtypes::EcRegion: case Subtypes::EcRegion:
if (!ec.isEmpty()) { case Subtypes::Reserved1Region:
msg(tr("buildIntelImage: more than one EC region found during image rebuild, the latest one is used"), index); case Subtypes::Reserved2Region:
} case Subtypes::Reserved3Region:
case Subtypes::Reserved4Region:
result = buildEcRegion(currentRegion, ec); // Add region as is
if (result) { region = model->header(currentRegion).append(model->body(currentRegion));
msg(tr("buildIntelImage: building of EC region failed with error \"%1\", original item data is used").arg(errorCodeToQString(result)), currentRegion);
ec = model->header(currentRegion).append(model->body(currentRegion));
}
break; break;
default: default:
msg(tr("buildIntelImage: don't know how to build region of unknown type"), index); msg(QObject::tr("buildIntelImage: don't know how to build region of unknown type"), index);
return ERR_UNKNOWN_ITEM_TYPE; return ERR_UNKNOWN_ITEM_TYPE;
} }
// Append the resulting region
intelImage.append(region);
} }
// Check size of new image, it must be same as old one // Check size of new image, it must be same as old one
UINT32 newSize = intelImage.size(); UINT32 newSize = intelImage.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)") msg(QObject::tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)") msg(QObject::tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
@ -252,27 +238,7 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildGbeRegion(const QModelIndex & index, QByteArray & region)
{
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildMeRegion(const QModelIndex & index, QByteArray & region)
{
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildPdrRegion(const QModelIndex & index, QByteArray & region)
{
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildEcRegion(const QModelIndex & index, QByteArray & region)
{
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -282,8 +248,6 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
if (!index.isValid()) if (!index.isValid())
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
STATUS result;
// No action required // No action required
if (model->action(index) == Actions::NoAction) { if (model->action(index) == Actions::NoAction) {
rawArea = model->header(index).append(model->body(index)); rawArea = model->header(index).append(model->body(index));
@ -299,6 +263,7 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
// Build children // Build children
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
STATUS result = ERR_SUCCESS;
QModelIndex currentChild = index.child(i, 0); QModelIndex currentChild = index.child(i, 0);
QByteArray currentData; QByteArray currentData;
// Check child type // Check child type
@ -309,13 +274,12 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
result = buildPadding(currentChild, currentData); result = buildPadding(currentChild, currentData);
} }
else { else {
msg(tr("buildRawArea: unexpected child item of type \"%1\" can't be processed, original item data is used").arg(itemTypeToQString(model->type(currentChild))), currentChild); msg(QObject::tr("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
result = ERR_SUCCESS;
currentData = model->header(currentChild).append(model->body(currentChild)); currentData = model->header(currentChild).append(model->body(currentChild));
} }
// Check build result // Check build result
if (result) { if (result) {
msg(tr("buildRawArea: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild); msg(QObject::tr("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
currentData = model->header(currentChild).append(model->body(currentChild)); currentData = model->header(currentChild).append(model->body(currentChild));
} }
// Append current data // Append current data
@ -326,12 +290,12 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
UINT32 newSize = rawArea.size(); UINT32 newSize = rawArea.size();
UINT32 oldSize = model->body(index).size(); UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) { if (newSize > oldSize) {
msg(tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)") msg(QObject::tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
else if (newSize < oldSize) { else if (newSize < oldSize) {
msg(tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)") msg(QObject::tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index); .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER; return ERR_INVALID_PARAMETER;
} }
@ -345,7 +309,7 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -365,11 +329,11 @@ STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
else if (model->action(index) == Actions::Erase) { else if (model->action(index) == Actions::Erase) {
padding = model->header(index).append(model->body(index)); padding = model->header(index).append(model->body(index));
if(erase(index, padding)) if(erase(index, padding))
msg(tr("buildPadding: erase failed, original item data is used"), index); msg(QObject::tr("buildPadding: erase failed, original item data is used"), index);
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -389,11 +353,11 @@ STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data
else if (model->action(index) == Actions::Erase) { else if (model->action(index) == Actions::Erase) {
data = model->header(index).append(model->body(index)); data = model->header(index).append(model->body(index));
if (erase(index, data)) if (erase(index, data))
msg(tr("buildNonUefiData: erase failed, original item data is used"), index); msg(QObject::tr("buildNonUefiData: erase failed, original item data is used"), index);
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -409,7 +373,7 @@ STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSp
return ERR_SUCCESS; return ERR_SUCCESS;
} }
msg(tr("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index); msg(QObject::tr("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -433,7 +397,4 @@ STATUS FfsBuilder::buildSection(const QModelIndex & index, QByteArray & section)
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
{
return ERR_NOT_IMPLEMENTED;
}

View File

@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __FFSBUILDER_H__ #ifndef __FFSBUILDER_H__
#define __FFSBUILDER_H__ #define __FFSBUILDER_H__
#include <vector>
#include <QObject> #include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
@ -25,31 +27,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffs.h" #include "ffs.h"
#include "utility.h" #include "utility.h"
class FfsBuilder : public QObject class FfsBuilder
{ {
Q_OBJECT
public: public:
explicit FfsBuilder(const TreeModel * treeModel, QObject *parent = 0); explicit FfsBuilder(const TreeModel * treeModel);
~FfsBuilder(); ~FfsBuilder();
QVector<QPair<QString, QModelIndex> > getMessages() const; std::vector<std::pair<QString, QModelIndex> > getMessages() const;
void clearMessages(); void clearMessages();
STATUS build(const QModelIndex & root, QByteArray & image); STATUS build(const QModelIndex & root, QByteArray & image);
private: private:
const TreeModel* model; const TreeModel* model;
QVector<QPair<QString, QModelIndex> > messagesVector; std::vector<std::pair<QString, QModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()); void msg(const QString & message, const QModelIndex &index = QModelIndex());
// UEFI standard structures
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule); STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage); STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
STATUS buildGbeRegion(const QModelIndex & index, QByteArray & region);
STATUS buildMeRegion(const QModelIndex & index, QByteArray & region);
STATUS buildPdrRegion(const QModelIndex & index, QByteArray & region);
STATUS buildEcRegion(const QModelIndex & index, QByteArray & region);
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true); STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true);
STATUS buildPadding(const QModelIndex & index, QByteArray & padding); STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
STATUS buildVolume(const QModelIndex & index, QByteArray & volume); STATUS buildVolume(const QModelIndex & index, QByteArray & volume);

View File

@ -13,8 +13,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsops.h" #include "ffsops.h"
FfsOperations::FfsOperations(const TreeModel* treeModel, QObject *parent) FfsOperations::FfsOperations(TreeModel* treeModel)
: QObject(parent), model(treeModel) : model(treeModel)
{ {
} }
@ -24,10 +24,10 @@ FfsOperations::~FfsOperations()
void FfsOperations::msg(const QString & message, const QModelIndex & index) void FfsOperations::msg(const QString & message, const QModelIndex & index)
{ {
messagesVector.push_back(QPair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
} }
QVector<QPair<QString, QModelIndex> > FfsOperations::getMessages() const std::vector<std::pair<QString, QModelIndex> > FfsOperations::getMessages() const
{ {
return messagesVector; return messagesVector;
} }
@ -89,13 +89,13 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
} }
} }
else if (mode == EXTRACT_MODE_BODY) { else if (mode == EXTRACT_MODE_BODY) {
name += tr("_body"); name += QObject::tr("_body");
// Extract without header and tail // Extract without header and tail
extracted.clear(); extracted.clear();
extracted.append(model->body(index)); extracted.append(model->body(index));
} }
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
name += tr("_body_unc"); name += QObject::tr("_body_unc");
// Extract without header and tail, uncompressed // Extract without header and tail, uncompressed
extracted.clear(); extracted.clear();
// There is no need to redo decompression, we can use child items // There is no need to redo decompression, we can use child items
@ -111,3 +111,58 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
return ERR_SUCCESS; return ERR_SUCCESS;
} }
STATUS FfsOperations::replace(const QModelIndex & index, const QString & data, const UINT8 mode)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
// Get data from parsing data
//PARSING_DATA pdata = parsingDataFromQModelIndex(index);
if (mode == REPLACE_MODE_AS_IS) {
return ERR_NOT_IMPLEMENTED;
}
else if (mode == REPLACE_MODE_BODY) {
return ERR_NOT_IMPLEMENTED;
}
else
return ERR_UNKNOWN_REPLACE_MODE;
return ERR_NOT_IMPLEMENTED;
}
STATUS FfsOperations::remove(const QModelIndex & index)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
// Set remove action
model->setAction(index, Actions::Remove);
return ERR_SUCCESS;
}
STATUS FfsOperations::rebuild(const QModelIndex & index)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
// On insert action, set insert action for children
//if (action == Actions::Insert)
// for (int i = 0; i < item->childCount(); i++)
// setAction(index.child(i, 0), Actions::Insert);
// Set rebuild action
model->setAction(index, Actions::Rebuild);
// Rebuild parent, if it has no action now
QModelIndex parent = index.parent();
if (parent.isValid() && model->type(parent) != Types::Root
&& model->action(parent) == Actions::NoAction)
rebuild(parent);
return ERR_SUCCESS;
}

View File

@ -14,32 +14,36 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __FFSOPS_H__ #ifndef __FFSOPS_H__
#define __FFSOPS_H__ #define __FFSOPS_H__
#include <vector>
#include <QObject> #include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
#include <QModelIndex> #include <QModelIndex>
#include "../common/basetypes.h" #include "basetypes.h"
#include "../common/treemodel.h" #include "treemodel.h"
#include "../common/ffs.h" #include "ffs.h"
#include "../common/utility.h" #include "utility.h"
class FfsOperations : public QObject class FfsOperations
{ {
Q_OBJECT
public: public:
explicit FfsOperations(const TreeModel * treeModel, QObject *parent = 0); explicit FfsOperations(TreeModel * treeModel);
~FfsOperations(); ~FfsOperations();
QVector<QPair<QString, QModelIndex> > getMessages() const; std::vector<std::pair<QString, QModelIndex> > getMessages() const;
void clearMessages(); void clearMessages();
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode); STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);
STATUS replace(const QModelIndex & index, const QString & data, const UINT8 mode);
STATUS remove(const QModelIndex & index);
STATUS rebuild(const QModelIndex & index);
private: private:
const TreeModel* model; TreeModel* model;
QVector<QPair<QString, QModelIndex> > messagesVector; std::vector<std::pair<QString, QModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()); void msg(const QString & message, const QModelIndex &index = QModelIndex());
}; };

File diff suppressed because it is too large Load Diff

View File

@ -13,13 +13,11 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __FFSPARSER_H__ #ifndef __FFSPARSER_H__
#define __FFSPARSER_H__ #define __FFSPARSER_H__
#include <QDir> #include <vector>
#include <QFile>
#include <QFileInfo>
#include <QObject> #include <QObject>
#include <QModelIndex> #include <QModelIndex>
#include <QByteArray> #include <QByteArray>
#include <QVector>
#include "basetypes.h" #include "basetypes.h"
#include "treemodel.h" #include "treemodel.h"
@ -36,22 +34,30 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
class TreeModel; class TreeModel;
class FfsParser : public QObject class FfsParser
{ {
Q_OBJECT
public: public:
// Default constructor and destructor // Default constructor and destructor
FfsParser(TreeModel* treeModel, QObject *parent = 0); FfsParser(TreeModel* treeModel);
~FfsParser(); ~FfsParser();
// Returns messages // Returns messages
QVector<QPair<QString, QModelIndex> > getMessages() const; std::vector<std::pair<QString, QModelIndex> > getMessages() const;
// Clears messages // Clears messages
void clearMessages(); void clearMessages();
// Firmware image parsing // Firmware image parsing
STATUS parse(const QByteArray &buffer); STATUS parse(const QByteArray &buffer);
// Retuns index of the last VTF after parsing is done
const QModelIndex getLastVtf() {return lastVtf;};
private:
TreeModel *model;
std::vector<std::pair<QString, QModelIndex> > messagesVector;
QModelIndex lastVtf;
UINT32 capsuleOffsetFixup;
STATUS parseRawArea(const QByteArray & data, const QModelIndex & index); STATUS parseRawArea(const QByteArray & data, const QModelIndex & index);
STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
STATUS parseVolumeBody(const QModelIndex & index); STATUS parseVolumeBody(const QModelIndex & index);
@ -60,15 +66,6 @@ public:
STATUS parseSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse = false); STATUS parseSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse = false);
STATUS parseSectionBody(const QModelIndex & index); STATUS parseSectionBody(const QModelIndex & index);
// Retuns index of the last VTF after parsing is done
const QModelIndex getLastVtf() {return lastVtf;};
private:
TreeModel *model;
QVector<QPair<QString, QModelIndex> > messagesVector;
QModelIndex lastVtf;
UINT32 capsuleOffsetFixup;
STATUS parseIntelImage(const QByteArray & intelImage, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & root); STATUS parseIntelImage(const QByteArray & intelImage, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & root);
STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index);
@ -78,8 +75,8 @@ private:
STATUS parsePadFileBody(const QModelIndex & index); STATUS parsePadFileBody(const QModelIndex & index);
STATUS parseVolumeNonUefiData(const QByteArray & data, const UINT32 parentOffset, const QModelIndex & index); STATUS parseVolumeNonUefiData(const QByteArray & data, const UINT32 parentOffset, const QModelIndex & index);
STATUS parseSections(const QByteArray & sections, const QModelIndex & index, const bool preparse = false);
STATUS parseSections(const QByteArray & sections, const QModelIndex & index, const bool preparse = false);
STATUS parseCommonSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse); STATUS parseCommonSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse);
STATUS parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse); STATUS parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse);
STATUS parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse); STATUS parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse);

View File

@ -10,12 +10,10 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include "fitparser.h" #include "fitparser.h"
#include "types.h"
#include "treemodel.h"
FitParser::FitParser(TreeModel* treeModel, QObject *parent) FitParser::FitParser(TreeModel* treeModel)
: QObject(parent), model(treeModel) : model(treeModel)
{ {
} }
@ -25,10 +23,10 @@ FitParser::~FitParser()
void FitParser::msg(const QString & message, const QModelIndex & index) void FitParser::msg(const QString & message, const QModelIndex & index)
{ {
messagesVector.push_back(QPair<QString, QModelIndex>(message, index)); messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
} }
QVector<QPair<QString, QModelIndex> > FitParser::getMessages() const std::vector<std::pair<QString, QModelIndex> > FitParser::getMessages() const
{ {
return messagesVector; return messagesVector;
} }
@ -73,23 +71,23 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
tempFitHeader->Checksum = 0; tempFitHeader->Checksum = 0;
UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize); UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize);
if (calculated != fitHeader->Checksum) { if (calculated != fitHeader->Checksum) {
msg(tr("Invalid FIT table checksum %1h, should be %2h").hexarg2(fitHeader->Checksum, 2).hexarg2(calculated, 2), fitIndex); msg(QObject::tr("Invalid FIT table checksum %1h, should be %2h").hexarg2(fitHeader->Checksum, 2).hexarg2(calculated, 2), fitIndex);
} }
} }
// Check fit header type // Check fit header type
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) { if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) {
msg(tr("Invalid FIT header type"), fitIndex); msg(QObject::tr("Invalid FIT header type"), fitIndex);
} }
// Add FIT header to fitTable // Add FIT header to fitTable
QVector<QString> currentStrings; std::vector<QString> currentStrings;
currentStrings += tr("_FIT_ "); currentStrings.push_back(QObject::tr("_FIT_ "));
currentStrings += tr("%1").hexarg2(fitSize, 8); currentStrings.push_back(QObject::tr("%1").hexarg2(fitSize, 8));
currentStrings += tr("%1").hexarg2(fitHeader->Version, 4); currentStrings.push_back(QObject::tr("%1").hexarg2(fitHeader->Version, 4));
currentStrings += fitEntryTypeToQString(fitHeader->Type); currentStrings.push_back(fitEntryTypeToQString(fitHeader->Type));
currentStrings += tr("%1").hexarg2(fitHeader->Checksum, 2); currentStrings.push_back(QObject::tr("%1").hexarg2(fitHeader->Checksum, 2));
fitTable.append(currentStrings); fitTable.push_back(currentStrings);
// Process all other entries // Process all other entries
bool msgModifiedImageMayNotWork = false; bool msgModifiedImageMayNotWork = false;
@ -100,7 +98,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
// Check entry type // Check entry type
switch (currentEntry->Type & 0x7F) { switch (currentEntry->Type & 0x7F) {
case FIT_TYPE_HEADER: case FIT_TYPE_HEADER:
msg(tr("Second FIT header found, the table is damaged"), fitIndex); msg(QObject::tr("Second FIT header found, the table is damaged"), fitIndex);
break; break;
case FIT_TYPE_EMPTY: case FIT_TYPE_EMPTY:
@ -120,16 +118,16 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
} }
// Add entry to fitTable // Add entry to fitTable
currentStrings += tr("%1").hexarg2(currentEntry->Address, 16); currentStrings.push_back(QObject::tr("%1").hexarg2(currentEntry->Address, 16));
currentStrings += tr("%1").hexarg2(currentEntry->Size, 8); currentStrings.push_back(QObject::tr("%1").hexarg2(currentEntry->Size, 8));
currentStrings += tr("%1").hexarg2(currentEntry->Version, 4); currentStrings.push_back(QObject::tr("%1").hexarg2(currentEntry->Version, 4));
currentStrings += fitEntryTypeToQString(currentEntry->Type); currentStrings.push_back(fitEntryTypeToQString(currentEntry->Type));
currentStrings += tr("%1").hexarg2(currentEntry->Checksum, 2); currentStrings.push_back(QObject::tr("%1").hexarg2(currentEntry->Checksum, 2));
fitTable.append(currentStrings); fitTable.push_back(currentStrings);
} }
if (msgModifiedImageMayNotWork) if (msgModifiedImageMayNotWork)
msg(tr("Opened image may not work after any modification")); msg(QObject::tr("Opened image may not work after any modification"));
return ERR_SUCCESS; return ERR_SUCCESS;
} }
@ -137,17 +135,17 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
QString FitParser::fitEntryTypeToQString(UINT8 type) QString FitParser::fitEntryTypeToQString(UINT8 type)
{ {
switch (type & 0x7F) { switch (type & 0x7F) {
case FIT_TYPE_HEADER: return tr("Header"); case FIT_TYPE_HEADER: return QObject::tr("Header");
case FIT_TYPE_MICROCODE: return tr("Microcode"); case FIT_TYPE_MICROCODE: return QObject::tr("Microcode");
case FIT_TYPE_BIOS_AC_MODULE: return tr("BIOS ACM"); case FIT_TYPE_BIOS_AC_MODULE: return QObject::tr("BIOS ACM");
case FIT_TYPE_BIOS_INIT_MODULE: return tr("BIOS Init"); case FIT_TYPE_BIOS_INIT_MODULE: return QObject::tr("BIOS Init");
case FIT_TYPE_TPM_POLICY: return tr("TPM Policy"); case FIT_TYPE_TPM_POLICY: return QObject::tr("TPM Policy");
case FIT_TYPE_BIOS_POLICY_DATA: return tr("BIOS Policy Data"); case FIT_TYPE_BIOS_POLICY_DATA: return QObject::tr("BIOS Policy Data");
case FIT_TYPE_TXT_CONF_POLICY: return tr("TXT Configuration Policy"); case FIT_TYPE_TXT_CONF_POLICY: return QObject::tr("TXT Configuration Policy");
case FIT_TYPE_AC_KEY_MANIFEST: return tr("BootGuard Key Manifest"); case FIT_TYPE_AC_KEY_MANIFEST: return QObject::tr("BootGuard Key Manifest");
case FIT_TYPE_AC_BOOT_POLICY: return tr("BootGuard Boot Policy"); case FIT_TYPE_AC_BOOT_POLICY: return QObject::tr("BootGuard Boot Policy");
case FIT_TYPE_EMPTY: return tr("Empty"); case FIT_TYPE_EMPTY: return QObject::tr("Empty");
default: return tr("Unknown"); default: return QObject::tr("Unknown");
} }
} }
@ -179,11 +177,11 @@ STATUS FitParser::findFitRecursive(const QModelIndex & index, QModelIndex & foun
if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) { if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) {
found = index; found = index;
fitOffset = offset; fitOffset = offset;
msg(tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found); msg(QObject::tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found);
return ERR_SUCCESS; return ERR_SUCCESS;
} }
else if (model->rowCount(index) == 0) // Show messages only to leaf items else if (model->rowCount(index) == 0) // Show messages only to leaf items
msg(tr("FIT table candidate found, but not referenced from the last VTF"), index); msg(QObject::tr("FIT table candidate found, but not referenced from the last VTF"), index);
} }
return ERR_SUCCESS; return ERR_SUCCESS;

View File

@ -13,42 +13,41 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef __FITPARSER_H__ #ifndef __FITPARSER_H__
#define __FITPARSER_H__ #define __FITPARSER_H__
#include <vector>
#include <QObject> #include <QObject>
#include <QModelIndex> #include <QModelIndex>
#include <QByteArray> #include <QByteArray>
#include <QStringList>
#include <QVector>
#include "basetypes.h"
#include "treemodel.h" #include "treemodel.h"
#include "utility.h" #include "utility.h"
#include "parsingdata.h" #include "parsingdata.h"
#include "fit.h" #include "fit.h"
#include "types.h"
#include "treemodel.h"
class TreeModel; class TreeModel;
class FitParser : public QObject class FitParser
{ {
Q_OBJECT
public: public:
// Default constructor and destructor // Default constructor and destructor
FitParser(TreeModel* treeModel, QObject *parent = 0); FitParser(TreeModel* treeModel);
~FitParser(); ~FitParser();
// Returns messages // Returns messages
QVector<QPair<QString, QModelIndex> > getMessages() const; std::vector<std::pair<QString, QModelIndex> > getMessages() const;
// Clears messages // Clears messages
void clearMessages(); void clearMessages();
STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf); STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf);
QVector<QVector<QString> > getFitTable() const { return fitTable; } std::vector<std::vector<QString> > getFitTable() const { return fitTable; }
private: private:
TreeModel *model; TreeModel *model;
QVector<QPair<QString, QModelIndex> > messagesVector; std::vector<std::pair<QString, QModelIndex> > messagesVector;
QModelIndex lastVtf; QModelIndex lastVtf;
QVector<QVector<QString> > fitTable; std::vector<std::vector<QString> > fitTable;
STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset); STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset);
QString fitEntryTypeToQString(UINT8 type); QString fitEntryTypeToQString(UINT8 type);

View File

@ -345,17 +345,6 @@ void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setAction(action); item->setAction(action);
// On insert action, set insert action for children
if (action == Actions::Insert)
for (int i = 0; i < item->childCount(); i++)
setAction(index.child(i, 0), Actions::Insert);
// Set rebuild action for parent, if it has no action now
if (index.parent().isValid() && this->type(index.parent()) != Types::Root
&& this->action(index.parent()) == Actions::NoAction)
setAction(index.parent(), Actions::Rebuild);
emit dataChanged(index, index); emit dataChanged(index, index);
} }

View File

@ -76,6 +76,7 @@ QString errorCodeToQString(UINT8 errorCode)
case ERR_CUSTOMIZED_DECOMPRESSION_FAILED: return QObject::tr("Customized compression failed"); case ERR_CUSTOMIZED_DECOMPRESSION_FAILED: return QObject::tr("Customized compression failed");
case ERR_UNKNOWN_COMPRESSION_TYPE: return QObject::tr("Unknown compression type"); case ERR_UNKNOWN_COMPRESSION_TYPE: return QObject::tr("Unknown compression type");
case ERR_UNKNOWN_EXTRACT_MODE: return QObject::tr("Unknown extract mode"); case ERR_UNKNOWN_EXTRACT_MODE: return QObject::tr("Unknown extract mode");
case ERR_UNKNOWN_REPLACE_MODE: return QObject::tr("Unknown replace mode");
//case ERR_UNKNOWN_INSERT_MODE: return QObject::tr("Unknown insert mode"); //case ERR_UNKNOWN_INSERT_MODE: return QObject::tr("Unknown insert mode");
case ERR_UNKNOWN_IMAGE_TYPE: return QObject::tr("Unknown executable image type"); case ERR_UNKNOWN_IMAGE_TYPE: return QObject::tr("Unknown executable image type");
case ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return QObject::tr("Unknown PE optional header type"); case ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE: return QObject::tr("Unknown PE optional header type");