Version 0.14.0

Refactoring of engine and UI code to use model instead of items
directly.
WARNING: this code is untested yet and commited not for release purposes
This commit is contained in:
Nikolaj Schlej 2013-12-29 16:13:46 +01:00
parent 9bc65c0590
commit 41fb0cbbf5
10 changed files with 1004 additions and 856 deletions

View File

@ -1,13 +1,13 @@
/* basetypes.h /* basetypes.h
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2013, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
@ -108,12 +108,52 @@ typedef uint16_t CHAR16;
// Search modes // Search modes
#define SEARCH_MODE_HEADER 1 #define SEARCH_MODE_HEADER 1
#define SEARCH_MODE_BODY 2 #define SEARCH_MODE_BODY 2
#define SEARCH_MODE_ALL 3 #define SEARCH_MODE_ALL 3
// Actions
enum ActionTypes {
NoAction = 50,
Create,
Insert,
Replace,
Remove,
Rebuild
};
// Types
enum ItemTypes {
Root = 60,
Capsule,
Image,
Region,
Padding,
Volume,
File,
Section
};
// Subtypes
enum ImageSubtypes{
IntelImage = 70,
BiosImage
};
enum CapsuleSubtypes {
AptioCapsule = 80,
UefiCapsule
};
enum RegionSubtypes {
DescriptorRegion = 90,
GbeRegion,
MeRegion,
BiosRegion,
PdrRegion
};
// EFI GUID // EFI GUID
typedef struct{ typedef struct{
UINT8 Data[16]; UINT8 Data[16];
} EFI_GUID; } EFI_GUID;
#define ALIGN4(Value) (((Value)+3) & ~3) #define ALIGN4(Value) (((Value)+3) & ~3)
#define ALIGN8(Value) (((Value)+7) & ~7) #define ALIGN8(Value) (((Value)+7) & ~7)

View File

@ -18,15 +18,15 @@ QString regionTypeToQString(const UINT8 type)
{ {
switch (type) switch (type)
{ {
case TreeItem::DescriptorRegion: case DescriptorRegion:
return QObject::tr("Descriptor"); return QObject::tr("Descriptor");
case TreeItem::GbeRegion: case GbeRegion:
return QObject::tr("GbE"); return QObject::tr("GbE");
case TreeItem::MeRegion: case MeRegion:
return QObject::tr("ME"); return QObject::tr("ME");
case TreeItem::BiosRegion: case BiosRegion:
return QObject::tr("BIOS"); return QObject::tr("BIOS");
case TreeItem::PdrRegion: case PdrRegion:
return QObject::tr("PDR"); return QObject::tr("PDR");
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
@ -58,4 +58,4 @@ UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit)
if (limit) if (limit)
return (limit + 1 - base) * 0x1000; return (limit + 1 - base) * 0x1000;
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <QQueue> #include <QQueue>
#include "basetypes.h" #include "basetypes.h"
#include "treeitem.h"
#include "treemodel.h" #include "treemodel.h"
#include "messagelistitem.h" #include "messagelistitem.h"
@ -33,15 +32,15 @@ public:
// Default constructor and destructor // Default constructor and destructor
FfsEngine(QObject *parent = 0); FfsEngine(QObject *parent = 0);
~FfsEngine(void); ~FfsEngine(void);
// Returns model for Qt view classes // Returns model for Qt view classes
TreeModel* model() const; TreeModel* treeModel() const;
// Returns message items queue // Returns message items queue
QQueue<MessageListItem> messages() const; QQueue<MessageListItem> messages() const;
// Clears message items queue // Clears message items queue
void clearMessages(); void clearMessages();
// Firmware image parsing // Firmware image parsing
UINT8 parseInputFile(const QByteArray & buffer); UINT8 parseInputFile(const QByteArray & buffer);
@ -63,7 +62,7 @@ public:
// Compression routines // Compression routines
UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedData, UINT8 * algorithm = NULL); UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedData, UINT8 * algorithm = NULL);
UINT8 compress(const QByteArray & data, const UINT8 algorithm, QByteArray & compressedData); UINT8 compress(const QByteArray & data, const UINT8 algorithm, QByteArray & compressedData);
// Construction routines // Construction routines
UINT8 reconstructImage(QByteArray & reconstructed); UINT8 reconstructImage(QByteArray & reconstructed);
UINT8 constructPadFile(const UINT32 size, const UINT8 revision, const UINT8 erasePolarity, QByteArray & pad); UINT8 constructPadFile(const UINT32 size, const UINT8 revision, const UINT8 erasePolarity, QByteArray & pad);
@ -71,32 +70,30 @@ public:
UINT8 growVolume(QByteArray & header, const UINT32 size, UINT32 & newSize); UINT8 growVolume(QByteArray & header, const UINT32 size, UINT32 & newSize);
// Operations on tree items // Operations on tree items
UINT8 extract(const QModelIndex & index, QByteArray & extracted, const UINT8 mode); UINT8 extract(const QModelIndex & index, QByteArray & extracted, const UINT8 mode);
UINT8 create(const QModelIndex & index, const UINT8 type, const QByteArray & header, const QByteArray & body, const UINT8 mode, const UINT8 action, const UINT8 algorithm = COMPRESSION_ALGORITHM_NONE); UINT8 create(const QModelIndex & index, const UINT8 type, const QByteArray & header, const QByteArray & body, const UINT8 mode, const UINT8 action, const UINT8 algorithm = COMPRESSION_ALGORITHM_NONE);
UINT8 insert(const QModelIndex & index, const QByteArray & object, const UINT8 mode); UINT8 insert(const QModelIndex & index, const QByteArray & object, const UINT8 mode);
UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode); UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode);
UINT8 remove(const QModelIndex & index); UINT8 remove(const QModelIndex & index);
UINT8 rebuild(const QModelIndex & index); UINT8 rebuild(const QModelIndex & index);
// Search routines // Search routines
UINT8 findHexPattern(const QByteArray & pattern, const UINT8 mode); UINT8 findHexPattern(const QByteArray & pattern, const UINT8 mode);
UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode); UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode);
UINT8 findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive); UINT8 findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
UINT8 findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive); UINT8 findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive);
private: private:
TreeItem *rootItem; TreeModel *model;
TreeModel *treeModel;
// Message helper
// Message helper
QQueue<MessageListItem> messageItems; QQueue<MessageListItem> messageItems;
void msg(const QString & message, const QModelIndex index = QModelIndex()); void msg(const QString & message, const QModelIndex index = QModelIndex());
// Internal operations // Internal operations
QModelIndex findParentOfType(UINT8 type, const QModelIndex & index) const;
bool hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2); bool hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
}; };

View File

@ -1,13 +1,13 @@
/* treeitem.cpp /* treeitem.cpp
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2013, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
@ -16,56 +16,56 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffs.h" #include "ffs.h"
#include "descriptor.h" #include "descriptor.h"
QString itemTypeToQString(const UINT8 type) QString itemTypeToQString(const UINT8 type)
{ {
switch (type) { switch (type) {
case TreeItem::Root: case Root:
return QObject::tr("Root"); return QObject::tr("Root");
case TreeItem::Image: case Image:
return QObject::tr("Image"); return QObject::tr("Image");
case TreeItem::Capsule: case Capsule:
return QObject::tr("Capsule"); return QObject::tr("Capsule");
case TreeItem::Region: case Region:
return QObject::tr("Region"); return QObject::tr("Region");
case TreeItem::Volume: case Volume:
return QObject::tr("Volume"); return QObject::tr("Volume");
case TreeItem::Padding: case Padding:
return QObject::tr("Padding"); return QObject::tr("Padding");
case TreeItem::File: case File:
return QObject::tr("File"); return QObject::tr("File");
case TreeItem::Section: case Section:
return QObject::tr("Section"); return QObject::tr("Section");
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
} }
} }
QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype) QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
{ {
switch (type) { switch (type) {
case TreeItem::Root: case Root:
case TreeItem::Image: case Image:
if (subtype == TreeItem::IntelImage) if (subtype == IntelImage)
return QObject::tr("Intel"); return QObject::tr("Intel");
else if (subtype == TreeItem::BiosImage) else if (subtype == BiosImage)
return QObject::tr("BIOS"); return QObject::tr("BIOS");
else else
return QObject::tr("Unknown"); return QObject::tr("Unknown");
case TreeItem::Padding: case Padding:
case TreeItem::Volume: case Volume:
return ""; return "";
case TreeItem::Capsule: case Capsule:
if (subtype == TreeItem::AptioCapsule) if (subtype == AptioCapsule)
return QObject::tr("Aptio extended"); return QObject::tr("Aptio extended");
else if (subtype == TreeItem::UefiCapsule) else if (subtype == UefiCapsule)
return QObject::tr("UEFI 2.0"); return QObject::tr("UEFI 2.0");
else else
return QObject::tr("Unknown"); return QObject::tr("Unknown");
case TreeItem::Region: case Region:
return regionTypeToQString(subtype); return regionTypeToQString(subtype);
case TreeItem::File: case File:
return fileTypeToQString(subtype); return fileTypeToQString(subtype);
case TreeItem::Section: case Section:
return sectionTypeToQString(subtype); return sectionTypeToQString(subtype);
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
@ -91,8 +91,8 @@ QString compressionTypeToQString(UINT8 algorithm)
} }
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, const UINT8 compression, TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, const UINT8 compression,
const QString & name, const QString & text, const QString & info, const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & tail, const QByteArray & header, const QByteArray & body, const QByteArray & tail,
TreeItem *parent) TreeItem *parent)
{ {
itemAction = NoAction; itemAction = NoAction;
@ -106,7 +106,7 @@ TreeItem::TreeItem(const UINT8 type, const UINT8 subtype, const UINT8 compressio
itemBody = body; itemBody = body;
itemTail = tail; itemTail = tail;
parentItem = parent; parentItem = parent;
// Set default names // Set default names
setDefaultNames(); setDefaultNames();
} }
@ -172,15 +172,15 @@ QVariant TreeItem::data(int column) const
case 0: //Name case 0: //Name
return itemName; return itemName;
case 1: //Action case 1: //Action
if (itemAction == TreeItem::Create) if (itemAction == Create)
return QObject::tr("Create"); return QObject::tr("Create");
if (itemAction == TreeItem::Insert) if (itemAction == Insert)
return QObject::tr("Insert"); return QObject::tr("Insert");
if (itemAction == TreeItem::Replace) if (itemAction == Replace)
return QObject::tr("Replace"); return QObject::tr("Replace");
if (itemAction == TreeItem::Remove) if (itemAction == Remove)
return QObject::tr("Remove"); return QObject::tr("Remove");
if (itemAction == TreeItem::Rebuild) if (itemAction == Rebuild)
return QObject::tr("Rebuild"); return QObject::tr("Rebuild");
return QVariant(); return QVariant();
case 2: //Type case 2: //Type
@ -286,13 +286,14 @@ void TreeItem::setAction(const UINT8 action)
{ {
itemAction = action; itemAction = action;
// On insert action, set insert action for children // On insert action, set insert action for children
if (action == TreeItem::Insert) if (action == Insert)
for(int i = 0; i < childCount(); i++) for(int i = 0; i < childCount(); i++)
child(i)->setAction(TreeItem::Insert); child(i)->setAction(Insert);
// Set rebuild action for parent, if it has no action now // Set rebuild action for parent, if it has no action now
if (parentItem && parentItem->type() != TreeItem::Root && parentItem->action() == TreeItem::NoAction) if (parentItem && parentItem->type() != Root
parentItem->setAction(TreeItem::Rebuild); && parentItem->action() == NoAction)
parentItem->setAction(Rebuild);
} }

View File

@ -1,13 +1,13 @@
/* treeitem.h /* treeitem.h
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2013, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
@ -28,55 +28,10 @@ extern QString compressionTypeToQString(UINT8 algorithm);
class TreeItem class TreeItem
{ {
public: public:
// Action types TreeItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
enum ActionTypes { const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
NoAction = 50,
Create,
Insert,
Replace,
Remove,
Rebuild
};
// Item types
enum ItemTypes {
Root = 60,
Capsule,
Image,
Region,
Padding,
Volume,
File,
Section
};
// Image subtypes
enum ImageSubtypes{
IntelImage = 70,
BiosImage
};
// Capsule subtypes
enum CapsuleSubtypes {
AptioCapsule = 80,
UefiCapsule
};
// Region subtypes
enum RegionSubtypes {
DescriptorRegion = 90,
GbeRegion,
MeRegion,
BiosRegion,
PdrRegion
};
// Constructor
TreeItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(), const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(),
TreeItem *parent = 0); TreeItem *parent = 0);
// Destructor
~TreeItem(); ~TreeItem();
// Operations with items // Operations with items
@ -107,8 +62,8 @@ public:
UINT8 compression() const; UINT8 compression() const;
// Some values can be changed after item construction // Some values can be changed after item construction
void setAction(const UINT8 action); void setAction(const UINT8 action);
void setTypeName(const QString &text); void setTypeName(const QString &text);
void setSubtypeName(const QString &text); void setSubtypeName(const QString &text);
void setName(const QString &text); void setName(const QString &text);
void setText(const QString &text); void setText(const QString &text);
@ -117,7 +72,7 @@ private:
// Set default names after construction // Set default names after construction
// They can later be changed by set* methods // They can later be changed by set* methods
void setDefaultNames(); void setDefaultNames();
QList<TreeItem*> childItems; QList<TreeItem*> childItems;
UINT8 itemAction; UINT8 itemAction;
UINT8 itemType; UINT8 itemType;
@ -126,8 +81,8 @@ private:
QByteArray itemHeader; QByteArray itemHeader;
QByteArray itemBody; QByteArray itemBody;
QByteArray itemTail; QByteArray itemTail;
QString itemName; QString itemName;
QString itemTypeName; QString itemTypeName;
QString itemSubtypeName; QString itemSubtypeName;
QString itemText; QString itemText;
QString itemInfo; QString itemInfo;

View File

@ -1,27 +1,28 @@
/* treemodel.cpp /* treemodel.cpp
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2013, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
#include "treeitem.h" #include "treeitem.h"
#include "treemodel.h" #include "treemodel.h"
TreeModel::TreeModel(TreeItem *root, QObject *parent) TreeModel::TreeModel(QObject *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
{ {
rootItem = root; rootItem = new TreeItem(Root);
} }
TreeModel::~TreeModel() TreeModel::~TreeModel()
{ {
delete rootItem;
} }
int TreeModel::columnCount(const QModelIndex &parent) const int TreeModel::columnCount(const QModelIndex &parent) const
@ -62,20 +63,20 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const int role) const
{ {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch(section) switch(section)
{ {
case 0: case 0:
return tr("Name"); return tr("Name");
case 1: case 1:
return tr("Action"); return tr("Action");
case 2: case 2:
return tr("Type"); return tr("Type");
case 3: case 3:
return tr("Subtype"); return tr("Subtype");
case 4: case 4:
return tr("Text"); return tr("Text");
} }
} }
return QVariant(); return QVariant();
} }
@ -108,7 +109,7 @@ QModelIndex TreeModel::parent(const QModelIndex &index) const
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer()); TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
if (childItem == rootItem) if (childItem == rootItem)
return QModelIndex(); return QModelIndex();
TreeItem *parentItem = childItem->parent(); TreeItem *parentItem = childItem->parent();
if (parentItem == rootItem) if (parentItem == rootItem)
@ -117,7 +118,6 @@ QModelIndex TreeModel::parent(const QModelIndex &index) const
return createIndex(parentItem->row(), 0, parentItem); return createIndex(parentItem->row(), 0, parentItem);
} }
int TreeModel::rowCount(const QModelIndex &parent) const int TreeModel::rowCount(const QModelIndex &parent) const
{ {
TreeItem *parentItem; TreeItem *parentItem;
@ -132,63 +132,213 @@ int TreeModel::rowCount(const QModelIndex &parent) const
return parentItem->childCount(); return parentItem->childCount();
} }
UINT8 TreeModel::setItemName(const QString &data, const QModelIndex &index) UINT8 TreeModel::type(const QModelIndex &index) const
{ {
if(!index.isValid()) if(!index.isValid())
return ERR_INVALID_PARAMETER; return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->type();
}
UINT8 TreeModel::subtype(const QModelIndex &index) const
{
if(!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->subtype();
}
QByteArray TreeModel::header(const QModelIndex &index) const
{
if(!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->header();
}
bool TreeModel::hasEmptyHeader(const QModelIndex &index) const
{
if(!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyHeader();
}
QByteArray TreeModel::body(const QModelIndex &index) const
{
if(!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->body();
}
bool TreeModel::hasEmptyBody(const QModelIndex &index) const
{
if(!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyBody();
}
QByteArray TreeModel::tail(const QModelIndex &index) const
{
if(!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->tail();
}
bool TreeModel::hasEmptyTail(const QModelIndex &index) const
{
if(!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyTail();
}
QString TreeModel::info(const QModelIndex &index) const
{
if(!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->info();
}
UINT8 TreeModel::action(const QModelIndex &index) const
{
if(!index.isValid())
return NoAction;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->action();
}
UINT8 TreeModel::compression(const QModelIndex &index) const
{
if(!index.isValid())
return COMPRESSION_ALGORITHM_UNKNOWN;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->compression();
}
void TreeModel::setNameString(const QModelIndex &index, const QString &data)
{
if(!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setName(data); item->setName(data);
emit dataChanged(index, index); emit dataChanged(index, index);
return ERR_SUCCESS;
} }
UINT8 TreeModel::setItemText(const QString &data, const QModelIndex &index) void TreeModel::setTypeString(const QModelIndex &index, const QString &data)
{ {
if(!index.isValid()) if(!index.isValid())
return ERR_INVALID_PARAMETER; return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setTypeName(data);
emit dataChanged(index, index);
}
void TreeModel::setSubtypeString(const QModelIndex &index, const QString &data)
{
if(!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setSubtypeName(data);
emit dataChanged(index, index);
}
void TreeModel::setTextString(const QModelIndex &index, const QString &data)
{
if(!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setText(data); item->setText(data);
emit dataChanged(index, index); emit dataChanged(index, index);
return ERR_SUCCESS;
} }
UINT8 TreeModel::setItemAction(const UINT8 action, const QModelIndex &index) QString TreeModel::nameString(const QModelIndex &index) const
{ {
if(!index.isValid()) if(!index.isValid())
return ERR_INVALID_PARAMETER; return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(0).toString();
}
QString TreeModel::actionString(const QModelIndex &index) const
{
if(!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(1).toString();}
QString TreeModel::typeString(const QModelIndex &index) const
{
if(!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(2).toString();
}
QString TreeModel::subtypeString(const QModelIndex &index) const
{
if(!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(3).toString();
}
QString TreeModel::textString(const QModelIndex &index) const
{
if(!index.isValid())
return QString();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(4).toString();
}
void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
{
if(!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setAction(action); item->setAction(action);
emit dataChanged(this->index(0,0), index); emit dataChanged(this->index(0,0), index);
return ERR_SUCCESS;
} }
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT8 compression, QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT8 compression,
const QString & name, const QString & text, const QString & info, const QString & name, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QByteArray & tail, const QByteArray & header, const QByteArray & body, const QByteArray & tail,
const QModelIndex & index, const UINT8 mode) const QModelIndex & parent, const UINT8 mode)
{ {
TreeItem *item = 0; TreeItem *item = 0;
TreeItem *parentItem = 0; TreeItem *parentItem = 0;
int parentColumn = 0; int parentColumn = 0;
if (!index.isValid()) if (!parent.isValid())
parentItem = rootItem; parentItem = rootItem;
else else
{ {
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) { if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) {
item = static_cast<TreeItem*>(index.internalPointer()); item = static_cast<TreeItem*>(parent.internalPointer());
parentItem = item->parent(); parentItem = item->parent();
parentColumn = index.parent().column(); parentColumn = parent.parent().column();
} }
else { else {
parentItem = static_cast<TreeItem*>(index.internalPointer()); parentItem = static_cast<TreeItem*>(parent.internalPointer());
parentColumn = index.column(); parentColumn = parent.column();
} }
} }
TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, tail, parentItem); TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, tail, parentItem);
if (mode == CREATE_MODE_APPEND) { if (mode == CREATE_MODE_APPEND) {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
@ -206,10 +356,28 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
parentItem->insertChildAfter(item, newItem); parentItem->insertChildAfter(item, newItem);
} }
else else
return QModelIndex(); return QModelIndex();
emit layoutChanged(); emit layoutChanged();
return createIndex(newItem->row(), parentColumn, newItem); return createIndex(newItem->row(), parentColumn, newItem);
} }
QModelIndex TreeModel::findParentOfType(const QModelIndex& index, UINT8 type) const
{
if(!index.isValid())
return QModelIndex();
TreeItem *item;
QModelIndex parent = index;
for(item = static_cast<TreeItem*>(parent.internalPointer());
item != NULL && item != rootItem && item->type() != type;
item = static_cast<TreeItem*>(parent.internalPointer()))
parent = parent.parent();
if (item != NULL && item != rootItem)
return parent;
return QModelIndex();
}

View File

@ -1,13 +1,13 @@
/* treemodel.h /* treemodel.h
Copyright (c) 2013, Nikolaj Schlej. All rights reserved. Copyright (c) 2013, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
@ -28,7 +28,7 @@ class TreeModel : public QAbstractItemModel
Q_OBJECT Q_OBJECT
public: public:
TreeModel(TreeItem *root, QObject *parent = 0); TreeModel(QObject *parent = 0);
~TreeModel(); ~TreeModel();
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
@ -40,15 +40,37 @@ public:
QModelIndex parent(const QModelIndex &index) const; QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const;
UINT8 setItemName(const QString &data, const QModelIndex &index); QString nameString(const QModelIndex &index) const;
UINT8 setItemText(const QString &data, const QModelIndex &index); QString actionString(const QModelIndex &index) const;
UINT8 setItemAction(const UINT8 action, const QModelIndex &index); QString typeString(const QModelIndex &index) const;
QString subtypeString(const QModelIndex &index) const;
QString textString(const QModelIndex &index) const;
void setAction(const QModelIndex &index, const UINT8 action);
void setTypeString(const QModelIndex &index, const QString &text);
void setSubtypeString(const QModelIndex &index, const QString &text);
void setNameString(const QModelIndex &index, const QString &text);
void setTextString(const QModelIndex &index, const QString &text);
UINT8 type(const QModelIndex &index) const;
UINT8 subtype(const QModelIndex &index) const;
QByteArray header(const QModelIndex &index) const;
bool hasEmptyHeader(const QModelIndex &index) const;
QByteArray body(const QModelIndex &index) const;
bool hasEmptyBody(const QModelIndex &index) const;
QByteArray tail(const QModelIndex &index) const;
bool hasEmptyTail(const QModelIndex &index) const;
QString info(const QModelIndex &index) const;
UINT8 action(const QModelIndex &index) const;
UINT8 compression(const QModelIndex &index) const;
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE, QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(), const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(), const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & tail = QByteArray(),
const QModelIndex & index = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND); const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;
private: private:
TreeItem *rootItem; TreeItem *rootItem;

View File

@ -21,23 +21,23 @@ UEFITool::UEFITool(QWidget *parent) :
// Create UI // Create UI
ui->setupUi(this); ui->setupUi(this);
searchDialog = new SearchDialog(this); searchDialog = new SearchDialog(this);
ffsEngine = NULL; ffsEngine = NULL;
// Connect signals to slots // Connect signals to slots
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile())); connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile())); connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search())); connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
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->actionInsertInto, SIGNAL(triggered()), this, SLOT(insertInto())); connect(ui->actionInsertInto, SIGNAL(triggered()), this, SLOT(insertInto()));
connect(ui->actionInsertBefore, SIGNAL(triggered()), this, SLOT(insertBefore())); connect(ui->actionInsertBefore, SIGNAL(triggered()), this, SLOT(insertBefore()));
connect(ui->actionInsertAfter, SIGNAL(triggered()), this, SLOT(insertAfter())); connect(ui->actionInsertAfter, SIGNAL(triggered()), this, SLOT(insertAfter()));
connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(replaceAsIs())); connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(replaceAsIs()));
connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody())); connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody()));
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove())); connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild())); connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages())); connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt())); connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit())); connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit()));
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings())); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings()));
@ -47,24 +47,24 @@ UEFITool::UEFITool(QWidget *parent) :
// Initialize non-persistent data // Initialize non-persistent data
init(); init();
// Read stored settings // Read stored settings
readSettings(); readSettings();
} }
UEFITool::~UEFITool() UEFITool::~UEFITool()
{ {
delete ui; delete ui;
delete ffsEngine; delete ffsEngine;
delete searchDialog; delete searchDialog;
} }
void UEFITool::init() void UEFITool::init()
{ {
// Clear components // Clear components
ui->messageListWidget->clear(); ui->messageListWidget->clear();
ui->infoEdit->clear(); ui->infoEdit->clear();
// Disable menus // Disable menus
ui->menuCapsuleActions->setDisabled(true); ui->menuCapsuleActions->setDisabled(true);
ui->menuImageActions->setDisabled(true); ui->menuImageActions->setDisabled(true);
@ -78,8 +78,8 @@ void UEFITool::init()
if (ffsEngine) if (ffsEngine)
delete ffsEngine; delete ffsEngine;
ffsEngine = new FfsEngine(this); ffsEngine = new FfsEngine(this);
ui->structureTreeView->setModel(ffsEngine->model()); ui->structureTreeView->setModel(ffsEngine->treeModel());
// Connect // Connect
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(populateUi(const QModelIndex &))); this, SLOT(populateUi(const QModelIndex &)));
@ -91,62 +91,62 @@ void UEFITool::populateUi(const QModelIndex &current)
if (!current.isValid()) if (!current.isValid())
return; return;
TreeItem* item = static_cast<TreeItem*>(current.internalPointer()); TreeModel* model = ffsEngine->treeModel();
UINT8 type = item->type(); UINT8 type = model->type(current);
UINT8 subtype = item->subtype(); UINT8 subtype = model->subtype(current);
// Set info text // Set info text
ui->infoEdit->setPlainText(item->info()); ui->infoEdit->setPlainText(model->info(current));
// Enable menus // Enable menus
ui->menuCapsuleActions->setEnabled(type == TreeItem::Capsule); ui->menuCapsuleActions->setEnabled(type == Capsule);
ui->menuImageActions->setEnabled(type == TreeItem::Image); ui->menuImageActions->setEnabled(type == Image);
ui->menuRegionActions->setEnabled(type == TreeItem::Region); ui->menuRegionActions->setEnabled(type == Region);
ui->menuPaddingActions->setEnabled(type == TreeItem::Padding); ui->menuPaddingActions->setEnabled(type == Padding);
ui->menuVolumeActions->setEnabled(type == TreeItem::Volume); ui->menuVolumeActions->setEnabled(type == Volume);
ui->menuFileActions->setEnabled(type == TreeItem::File); ui->menuFileActions->setEnabled(type == File);
ui->menuSectionActions->setEnabled(type == TreeItem::Section); ui->menuSectionActions->setEnabled(type == Section);
// Enable actions // Enable actions
ui->actionExtract->setDisabled(item->hasEmptyHeader() && item->hasEmptyBody() && item->hasEmptyTail()); ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
ui->actionRebuild->setDisabled(item->hasEmptyHeader() && item->hasEmptyBody() && item->hasEmptyTail()); ui->actionRebuild->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
ui->actionExtractBody->setDisabled(item->hasEmptyHeader()); ui->actionExtractBody->setDisabled(model->hasEmptyHeader(current));
ui->actionRemove->setEnabled(type == TreeItem::Volume || type == TreeItem::File || type == TreeItem::Section); ui->actionRemove->setEnabled(type == Volume || type == File || type == Section);
ui->actionInsertInto->setEnabled(type == TreeItem::Volume || (type == TreeItem::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD)); ui->actionInsertInto->setEnabled(type == Volume || (type == File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD));
ui->actionInsertBefore->setEnabled(type == TreeItem::File || type == TreeItem::Section); ui->actionInsertBefore->setEnabled(type == File || type == Section);
ui->actionInsertAfter->setEnabled(type == TreeItem::File || type == TreeItem::Section); ui->actionInsertAfter->setEnabled(type == File || type == Section);
ui->actionReplace->setEnabled(type == TreeItem::File || type == TreeItem::Section); ui->actionReplace->setEnabled(type == File || type == Section);
ui->actionReplaceBody->setEnabled(type == TreeItem::File || type == TreeItem::Section); ui->actionReplaceBody->setEnabled(type == File || type == Section);
} }
void UEFITool::search() void UEFITool::search()
{ {
if (searchDialog->exec() != QDialog::Accepted) if (searchDialog->exec() != QDialog::Accepted)
return; return;
int index = searchDialog->ui->dataTypeComboBox->currentIndex(); int index = searchDialog->ui->dataTypeComboBox->currentIndex();
if (index == 0) { // Hex pattern if (index == 0) { // Hex pattern
QByteArray pattern = QByteArray::fromHex(searchDialog->ui->searchEdit->text().toLatin1()); QByteArray pattern = QByteArray::fromHex(searchDialog->ui->searchEdit->text().toLatin1());
if (pattern.isEmpty()) if (pattern.isEmpty())
return; return;
UINT8 mode; UINT8 mode;
if (searchDialog->ui->headerOnlyRadioButton->isChecked()) if (searchDialog->ui->headerOnlyRadioButton->isChecked())
mode = SEARCH_MODE_HEADER; mode = SEARCH_MODE_HEADER;
else if (searchDialog->ui->bodyOnlyRadioButton->isChecked()) else if (searchDialog->ui->bodyOnlyRadioButton->isChecked())
mode = SEARCH_MODE_BODY; mode = SEARCH_MODE_BODY;
else else
mode = SEARCH_MODE_ALL; mode = SEARCH_MODE_ALL;
ffsEngine->findHexPattern(pattern, mode); ffsEngine->findHexPattern(pattern, mode);
showMessages(); showMessages();
} }
else if (index == 1) { // Text string else if (index == 1) { // Text string
QString pattern = searchDialog->ui->searchEdit->text(); QString pattern = searchDialog->ui->searchEdit->text();
if (pattern.isEmpty()) if (pattern.isEmpty())
return; return;
ffsEngine->findTextPattern(pattern, searchDialog->ui->unicodeCheckBox->isChecked(), ffsEngine->findTextPattern(pattern, searchDialog->ui->unicodeCheckBox->isChecked(),
(Qt::CaseSensitivity) searchDialog->ui->caseSensitiveCheckBox->isChecked()); (Qt::CaseSensitivity) searchDialog->ui->caseSensitiveCheckBox->isChecked());
showMessages(); showMessages();
} }
} }
void UEFITool::rebuild() void UEFITool::rebuild()
@ -156,7 +156,7 @@ void UEFITool::rebuild()
return; return;
UINT8 result = ffsEngine->rebuild(index); UINT8 result = ffsEngine->rebuild(index);
if (result == ERR_SUCCESS) if (result == ERR_SUCCESS)
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
} }
@ -178,26 +178,26 @@ void UEFITool::insert(const UINT8 mode)
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); TreeModel* model = ffsEngine->treeModel();
UINT8 type; UINT8 type;
UINT8 objectType; UINT8 objectType;
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER) if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER)
type = item->parent()->type(); type = model->type(index.parent());
else else
type = item->type(); type = model->type(index);
QString path; QString path;
switch (type) { switch (type) {
case TreeItem::Volume: case Volume:
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS files (*.ffs *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS files (*.ffs *.bin);;All files (*.*)");
objectType = TreeItem::File; objectType = File;
break; break;
case TreeItem::File: case File:
case TreeItem::Section: case Section:
path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"),".","Section files (*.sct *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"),".","Section files (*.sct *.bin);;All files (*.*)");
objectType = TreeItem::Section; objectType = Section;
break; break;
default: default:
return; return;
@ -254,48 +254,48 @@ 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;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); TreeModel* model = ffsEngine->treeModel();
QString path; QString path;
if (item->type() == TreeItem::File) { if (model->type(index) == 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"),".","FFS files (*.ffs *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace selected object"),".","FFS files (*.ffs *.bin);;All files (*.*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (item->subtype() == EFI_FV_FILETYPE_ALL || item->subtype() == 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"),".","Raw files (*.raw *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"),".","Raw files (*.raw *.bin);;All files (*.*)");
else if (item->subtype() == 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
return; return;
else else
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace body"),".","FFS file body files (*.fbd *.bin);;All files (*.*)");
} }
else else
return; return;
} }
else if (item->type() == TreeItem::Section) { else if (model->type(index) == 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"),".","Section files (*.sec *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"),".","Section files (*.sec *.bin);;All files (*.*)");
} }
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
if (item->subtype() == EFI_SECTION_COMPRESSION || item->subtype() == EFI_SECTION_GUID_DEFINED || item->subtype() == 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"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace body"),".","FFS file body files (*.fbd *.bin);;All files (*.*)");
else if (item->subtype() == 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"),".","Volume files (*.vol *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace body"),".","Volume files (*.vol *.bin);;All files (*.*)");
else if (item->subtype() == EFI_SECTION_RAW) else if (model->subtype(index) == EFI_SECTION_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"),".","Raw files (*.raw *.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace body"),".","Raw files (*.raw *.bin);;All files (*.*)");
else else
path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getOpenFileName(this, tr("Select file to replace body"),".","Binary files (*.bin);;All files (*.*)");
} }
else else
return; return;
} }
else else
return; return;
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 existing file"));
return; return;
@ -334,68 +334,68 @@ void UEFITool::extract(const UINT8 mode)
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid()) if (!index.isValid())
return; return;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); TreeModel* model = ffsEngine->treeModel();
UINT8 type = item->type(); UINT8 type = model->type(index);
QString path; QString path;
if (mode == EXTRACT_MODE_AS_IS) { if (mode == EXTRACT_MODE_AS_IS) {
switch (type) { switch (type) {
case TreeItem::Capsule: case Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"),".","Capsule files (*.cap *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"),".","Capsule files (*.cap *.bin);;All files (*.*)");
break; break;
case TreeItem::Image: case Image:
path = QFileDialog::getSaveFileName(this, tr("Save image to file"),".","Image files (*.rom *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save image to file"),".","Image files (*.rom *.bin);;All files (*.*)");
break; break;
case TreeItem::Region: case Region:
path = QFileDialog::getSaveFileName(this, tr("Save region to file"),".","Region files (*.rgn *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save region to file"),".","Region files (*.rgn *.bin);;All files (*.*)");
break; break;
case TreeItem::Padding: case Padding:
path = QFileDialog::getSaveFileName(this, tr("Save padding to file"),".","Padding files (*.pad *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save padding to file"),".","Padding files (*.pad *.bin);;All files (*.*)");
break; break;
case TreeItem::Volume: case Volume:
path = QFileDialog::getSaveFileName(this, tr("Save volume to file"),".","Volume files (*.vol *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save volume to file"),".","Volume files (*.vol *.bin);;All files (*.*)");
break; break;
case TreeItem::File: case File:
path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"),".","FFS files (*.ffs *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"),".","FFS files (*.ffs *.bin);;All files (*.*)");
break; break;
case TreeItem::Section: case Section:
path = QFileDialog::getSaveFileName(this, tr("Save section file to file"),".","Section files (*.sct *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save section file to file"),".","Section files (*.sct *.bin);;All files (*.*)");
break; break;
default: default:
path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)");
} }
} }
else if (mode == EXTRACT_MODE_BODY) { else if (mode == EXTRACT_MODE_BODY) {
switch (type) { switch (type) {
case TreeItem::Capsule: case Capsule:
path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"),".","Image files (*.rom *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"),".","Image files (*.rom *.bin);;All files (*.*)");
break; break;
case TreeItem::File: { case File: {
if (item->subtype() == EFI_FV_FILETYPE_ALL || item->subtype() == EFI_FV_FILETYPE_RAW) if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW)
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"),".","Raw files (*.raw *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"),".","Raw files (*.raw *.bin);;All files (*.*)");
else else
path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)");
} }
break; break;
case TreeItem::Section: { case Section: {
if (item->subtype() == EFI_SECTION_COMPRESSION || item->subtype() == EFI_SECTION_GUID_DEFINED || item->subtype() == 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::getSaveFileName(this, tr("Save encapsulated section body to FFS body file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save encapsulated section body to FFS body file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)");
else if (item->subtype() == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"),".","Volume files (*.vol *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"),".","Volume files (*.vol *.bin);;All files (*.*)");
else if (item->subtype() == EFI_SECTION_RAW) else if (model->subtype(index) == EFI_SECTION_RAW)
path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"),".","Raw files (*.raw *.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"),".","Raw files (*.raw *.bin);;All files (*.*)");
else else
path = QFileDialog::getSaveFileName(this, tr("Save section body to file"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save section body to file"),".","Binary files (*.bin);;All files (*.*)");
} }
break; break;
default: default:
path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)");
} }
} }
else else
path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)");
QFile outputFile; QFile outputFile;
outputFile.setFileName(path); outputFile.setFileName(path);
if (!outputFile.open(QFile::WriteOnly)) { if (!outputFile.open(QFile::WriteOnly)) {
@ -405,7 +405,7 @@ void UEFITool::extract(const UINT8 mode)
QByteArray extracted; QByteArray extracted;
UINT8 result = ffsEngine->extract(index, extracted, mode); UINT8 result = ffsEngine->extract(index, extracted, mode);
if (result) if (result)
ui->statusBar->showMessage(tr("File can't be extracted (%1)").arg(result)); ui->statusBar->showMessage(tr("File can't be extracted (%1)").arg(result));
else { else {
outputFile.resize(0); outputFile.resize(0);
@ -433,7 +433,7 @@ void UEFITool::aboutQt()
void UEFITool::exit() void UEFITool::exit()
{ {
QCoreApplication::exit(0); QCoreApplication::exit(0);
} }
void UEFITool::saveImageFile() void UEFITool::saveImageFile()
@ -445,8 +445,8 @@ void UEFITool::saveImageFile()
if (!outputFile.open(QFile::WriteOnly)) { if (!outputFile.open(QFile::WriteOnly)) {
ui->statusBar->showMessage(tr("Can't open file for writing")); ui->statusBar->showMessage(tr("Can't open file for writing"));
return; return;
} }
QByteArray reconstructed; QByteArray reconstructed;
UINT8 result = ffsEngine->reconstructImage(reconstructed); UINT8 result = ffsEngine->reconstructImage(reconstructed);
showMessages(); showMessages();
@ -501,15 +501,15 @@ void UEFITool::openImageFile(QString path)
else else
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName())); ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
// Enable search // Enable search
ui->actionSearch->setEnabled(true); ui->actionSearch->setEnabled(true);
} }
void UEFITool::clearMessages() void UEFITool::clearMessages()
{ {
ffsEngine->clearMessages(); ffsEngine->clearMessages();
messageItems.clear(); messageItems.clear();
ui->messageListWidget->clear(); ui->messageListWidget->clear();
} }
void UEFITool::dragEnterEvent(QDragEnterEvent* event) void UEFITool::dragEnterEvent(QDragEnterEvent* event)
@ -540,8 +540,8 @@ void UEFITool::scrollTreeView(QListWidgetItem* item)
{ {
MessageListItem* messageItem = (MessageListItem*) item; MessageListItem* messageItem = (MessageListItem*) item;
QModelIndex index = messageItem->index(); QModelIndex index = messageItem->index();
if (index.isValid()) { if (index.isValid()) {
ui->structureTreeView->scrollTo(index); ui->structureTreeView->scrollTo(index);
ui->structureTreeView->selectionModel()->clearSelection(); ui->structureTreeView->selectionModel()->clearSelection();
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select); ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
} }
@ -550,40 +550,40 @@ void UEFITool::scrollTreeView(QListWidgetItem* item)
void UEFITool::contextMenuEvent(QContextMenuEvent* event) void UEFITool::contextMenuEvent(QContextMenuEvent* event)
{ {
if (ui->messageListWidget->underMouse()) { if (ui->messageListWidget->underMouse()) {
ui->menuMessages->exec(event->globalPos()); ui->menuMessages->exec(event->globalPos());
return;
}
if(!ui->structureTreeView->underMouse())
return; return;
}
QPoint pt = event->pos();
if(!ui->structureTreeView->underMouse())
return;
QPoint pt = event->pos();
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
if(!index.isValid()) if(!index.isValid())
return; return;
TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); TreeModel* model = ffsEngine->treeModel();
switch(item->type()) switch(model->type(index))
{ {
case TreeItem::Capsule: case Capsule:
ui->menuCapsuleActions->exec(event->globalPos()); ui->menuCapsuleActions->exec(event->globalPos());
break; break;
case TreeItem::Image: case Image:
ui->menuImageActions->exec(event->globalPos()); ui->menuImageActions->exec(event->globalPos());
break; break;
case TreeItem::Region: case Region:
ui->menuRegionActions->exec(event->globalPos()); ui->menuRegionActions->exec(event->globalPos());
break; break;
case TreeItem::Padding: case Padding:
ui->menuPaddingActions->exec(event->globalPos()); ui->menuPaddingActions->exec(event->globalPos());
break; break;
case TreeItem::Volume: case Volume:
ui->menuVolumeActions->exec(event->globalPos()); ui->menuVolumeActions->exec(event->globalPos());
break; break;
case TreeItem::File: case File:
ui->menuFileActions->exec(event->globalPos()); ui->menuFileActions->exec(event->globalPos());
break; break;
case TreeItem::Section: case Section:
ui->menuSectionActions->exec(event->globalPos()); ui->menuSectionActions->exec(event->globalPos());
break; break;
} }
@ -591,35 +591,35 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
void UEFITool::readSettings() void UEFITool::readSettings()
{ {
QSettings settings("UEFITool.ini", QSettings::IniFormat, this); QSettings settings("UEFITool.ini", QSettings::IniFormat, this);
resize(settings.value("mainWindow/size", QSize(800, 600)).toSize()); resize(settings.value("mainWindow/size", QSize(800, 600)).toSize());
move(settings.value("mainWindow/position", QPoint(0, 0)).toPoint()); move(settings.value("mainWindow/position", QPoint(0, 0)).toPoint());
QList<int> horList, vertList; QList<int> horList, vertList;
horList.append(settings.value("mainWindow/treeWidth", 600).toInt()); horList.append(settings.value("mainWindow/treeWidth", 600).toInt());
horList.append(settings.value("mainWindow/infoWidth", 180).toInt()); horList.append(settings.value("mainWindow/infoWidth", 180).toInt());
vertList.append(settings.value("mainWindow/treeHeight", 400).toInt()); vertList.append(settings.value("mainWindow/treeHeight", 400).toInt());
vertList.append(settings.value("mainWindow/messageHeight", 180).toInt()); vertList.append(settings.value("mainWindow/messageHeight", 180).toInt());
ui->infoSplitter->setSizes(horList); ui->infoSplitter->setSizes(horList);
ui->messagesSplitter->setSizes(vertList); ui->messagesSplitter->setSizes(vertList);
ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt()); ui->structureTreeView->setColumnWidth(0, settings.value("tree/columnWidth0", ui->structureTreeView->columnWidth(0)).toInt());
ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt()); ui->structureTreeView->setColumnWidth(1, settings.value("tree/columnWidth1", ui->structureTreeView->columnWidth(1)).toInt());
ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt());
ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt());
//ui->structureTreeView->setColumnWidth(4, settings.value("tree/columnWidth4", 10).toInt()); //ui->structureTreeView->setColumnWidth(4, settings.value("tree/columnWidth4", 10).toInt());
} }
void UEFITool::writeSettings() void UEFITool::writeSettings()
{ {
QSettings settings("UEFITool.ini", QSettings::IniFormat, this); QSettings settings("UEFITool.ini", QSettings::IniFormat, this);
settings.setValue("mainWindow/size", size()); settings.setValue("mainWindow/size", size());
settings.setValue("mainWindow/position", pos()); settings.setValue("mainWindow/position", pos());
settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width()); settings.setValue("mainWindow/treeWidth", ui->structureGroupBox->width());
settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width()); settings.setValue("mainWindow/infoWidth", ui->infoGroupBox->width());
settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height()); settings.setValue("mainWindow/treeHeight", ui->structureGroupBox->height());
settings.setValue("mainWindow/messageHeight", ui->messageGroupBox->height()); settings.setValue("mainWindow/messageHeight", ui->messageGroupBox->height());
settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0)); settings.setValue("tree/columnWidth0", ui->structureTreeView->columnWidth(0));
settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1)); settings.setValue("tree/columnWidth1", ui->structureTreeView->columnWidth(1));
settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2));
settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3));
//settings.setValue("tree/columnWidth4", ui->structureTreeView->columnWidth(4)); //settings.setValue("tree/columnWidth4", ui->structureTreeView->columnWidth(4));
} }

View File

@ -20,7 +20,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>UEFITool 0.13.0</string> <string>UEFITool 0.14.0</string>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="centralWidget">
<property name="sizePolicy"> <property name="sizePolicy">