Version 0.3.0

Refactor code to separate GUI from FFS ttraversal
This commit is contained in:
Nikolaj Schlej 2013-10-15 17:19:15 +02:00
parent 1827c94977
commit 3ffbc01a3f
17 changed files with 1570 additions and 1081 deletions

View file

@ -13,41 +13,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h"
#include "treemodel.h"
#include "ffs.h"
#include "descriptor.h"
TreeModel::TreeModel(QObject *parent)
TreeModel::TreeModel(TreeItem *root, QObject *parent)
: QAbstractItemModel(parent)
{
rootItem = new TreeItem(RootItem, 0, tr("Object"), tr("Type"), tr("Subtype"), tr("Text"));
rootItem = root;
}
TreeModel::~TreeModel()
{
delete rootItem;
}
bool TreeModel::hasEmptyHeader(const QModelIndex& index)
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyHeader();
}
bool TreeModel::hasEmptyBody(const QModelIndex& index)
{
if (!index.isValid())
return true;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->hasEmptyBody();
}
int TreeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
@ -140,153 +116,6 @@ int TreeModel::rowCount(const QModelIndex &parent) const
return parentItem->childCount();
}
QModelIndex TreeModel::addItem(UINT8 type, UINT8 subtype, const QByteArray &header, const QByteArray &body, const QModelIndex &parent)
{
TreeItem *parentItem;
int parentColumn = 0;
if (!parent.isValid())
parentItem = rootItem;
else
{
parentItem = static_cast<TreeItem*>(parent.internalPointer());
parentColumn = parent.column();
}
// All information extraction must be here
QString name, typeName, subtypeName, info;
EFI_CAPSULE_HEADER* capsuleHeader;
APTIO_CAPSULE_HEADER* aptioCapsuleHeader;
FLASH_DESCRIPTOR_MAP* descriptorMap;
//FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection;
//FLASH_DESCRIPTOR_REGION_SECTION* regionSection;
//FLASH_DESCRIPTOR_MASTER_SECTION* masterSection;
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader;
EFI_FFS_FILE_HEADER* fileHeader;
//EFI_COMMON_SECTION_HEADER* sectionHeader;
switch (type)
{
case RootItem:
// Do not allow to add another root item
return QModelIndex();
break;
case CapsuleItem:
//typeName = tr("Capsule");
switch (subtype)
{
case AptioCapsule:
name = tr("AMI Aptio capsule");
aptioCapsuleHeader = (APTIO_CAPSULE_HEADER*) header.constData();
info = tr("GUID: %1\nHeader size: %2\nFlags: %3\nImage size: %4")
.arg(guidToQString(aptioCapsuleHeader->CapsuleHeader.CapsuleGuid))
.arg(aptioCapsuleHeader->CapsuleHeader.Flags, 8, 16, QChar('0'))
.arg(aptioCapsuleHeader->RomImageOffset, 4, 16, QChar('0'))
.arg(aptioCapsuleHeader->CapsuleHeader.CapsuleImageSize - aptioCapsuleHeader->RomImageOffset, 8, 16, QChar('0'));
//!TODO: more info about Aptio capsule
break;
case UefiCapsule:
name = tr("UEFI capsule");
capsuleHeader = (EFI_CAPSULE_HEADER*) header.constData();
info = tr("GUID: %1\nHeader size: %2\nFlags: %3\nImage size: %4")
.arg(guidToQString(capsuleHeader->CapsuleGuid))
.arg(capsuleHeader->Flags, 8, 16, QChar('0'))
.arg(capsuleHeader->HeaderSize, 8, 16, QChar('0'))
.arg(capsuleHeader->CapsuleImageSize, 8, 16, QChar('0'));
break;
default:
name = tr("Unknown capsule");
info = tr("GUID: %1\n").arg(guidToQString(*(EFI_GUID*)header.constData()));
break;
}
break;
case DescriptorItem:
name = tr("Descriptor");
descriptorMap = (FLASH_DESCRIPTOR_MAP*) body.constData();
info = tr("Flash chips: %1\nRegions: %2\nMasters: %3\nPCH straps:%4\nPROC straps: %5\nICC table entries: %6")
.arg(descriptorMap->NumberOfFlashChips + 1) //
.arg(descriptorMap->NumberOfRegions + 1) // Zero-based numbers in storage
.arg(descriptorMap->NumberOfMasters + 1) //
.arg(descriptorMap->NumberOfPchStraps)
.arg(descriptorMap->NumberOfProcStraps)
.arg(descriptorMap->NumberOfIccTableEntries);
//!TODO: more info about descriptor
break;
case RegionItem:
typeName = tr("Region");
info = tr("Size: %1").arg(body.size(), 8, 16, QChar('0'));
//!TODO: more info about GbE and ME regions
switch (subtype)
{
case GbeRegion:
name = tr("GbE region");
break;
case MeRegion:
name = tr("ME region");
break;
case BiosRegion:
name = tr("BIOS region");
break;
case PdrRegion:
name = tr("PDR region");
break;
default:
name = tr("Unknown region");
break;
}
break;
case PaddingItem:
name = tr("Padding");
info = tr("Size: %1").arg(body.size(), 8, 16, QChar('0'));
break;
case VolumeItem:
typeName = tr("Volume");
// Parse volume header to determine its revision and file system
volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*) header.constData();
name = guidToQString(volumeHeader->FileSystemGuid);
subtypeName = tr("Revision %1").arg(volumeHeader->Revision);
info = tr("Size: %1\nSignature: %2\nAttributes: %3\nHeader size: %4")
.arg(volumeHeader->FvLength, 8, 16, QChar('0'))
.arg(volumeHeader->Signature, 8, 16, QChar('0'))
.arg(volumeHeader->Attributes, 8, 16, QChar('0'))
.arg(volumeHeader->HeaderLength, 4, 16, QChar('0'));
break;
case FileItem:
typeName = tr("File");
// Parse file header to determine its GUID and type
fileHeader = (EFI_FFS_FILE_HEADER*) header.constData();
name = guidToQString(fileHeader->Name);
subtypeName = fileTypeToQString(subtype);
info = tr("Type: %1\nAttributes: %2\nSize: %3\nState: %4")
.arg(fileHeader->Type, 2, 16, QChar('0'))
.arg(fileHeader->Attributes, 2, 16, QChar('0'))
.arg(uint24ToUint32(fileHeader->Size), 6, 16, QChar('0'))
.arg(fileHeader->State, 2, 16, QChar('0'));
break;
case SectionItem:
typeName = tr("Section");
name = sectionTypeToQString(subtype) + tr(" section");
info = tr("Size: %1").arg(body.size(), 8, 16, QChar('0'));
//!TODO: add more specific info for all section types with uncommon headers
// Set name of file
if (subtype == UserInterfaceSection)
{
QString text = QString::fromUtf16((const ushort*)body.constData());
setItemText(text, findParentOfType(FileItem, parent));
}
break;
default:
name = tr("Unknown");
break;
}
emit layoutAboutToBeChanged();
TreeItem *item = new TreeItem(type, subtype, name, typeName, subtypeName, "", info, header, body, parentItem);
parentItem->appendChild(item);
emit layoutChanged();
return createIndex(parentItem->childCount() - 1, parentColumn, item);
}
bool TreeModel::setItemName(const QString &data, const QModelIndex &index)
{
if(!index.isValid())
@ -309,46 +138,24 @@ bool TreeModel::setItemText(const QString &data, const QModelIndex &index)
return true;
}
bool TreeModel::removeItem(const QModelIndex &index)
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT32 offset, const QString & name, const QString & typeName,
const QString & subtypeName, const QString & text, const QString & info,
const QByteArray & header, const QByteArray & body, const QModelIndex & parent)
{
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->parent()->removeChild(item);
delete item;
return true;
}
TreeItem *parentItem;
int parentColumn = 0;
QModelIndex TreeModel::findParentOfType(UINT8 type, const QModelIndex& index)
{
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;
if (!parent.isValid())
parentItem = rootItem;
else
{
parentItem = static_cast<TreeItem*>(parent.internalPointer());
parentColumn = parent.column();
}
return QModelIndex();
}
QByteArray TreeModel::header(const QModelIndex& index)
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->header();
}
QByteArray TreeModel::body(const QModelIndex& index)
{
if (!index.isValid())
return QByteArray();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->body();
emit layoutAboutToBeChanged();
TreeItem *item = new TreeItem(type, subtype, offset, name, typeName, subtypeName, text, info, header, body, parentItem);
parentItem->appendChild(item);
emit layoutChanged();
return createIndex(parentItem->childCount() - 1, parentColumn, item);
}