NE alpha10

- added FIT messages widget and related messages
- corrected small text issues
This commit is contained in:
Nikolaj Schlej 2015-09-13 16:36:43 +02:00
parent cc49cbcdd1
commit f6c429f00c
6 changed files with 100 additions and 30 deletions

View File

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
version(tr("0.30.0_alpha9"))
version(tr("0.30.0_alpha10"))
{
clipboard = QApplication::clipboard();
@ -72,6 +72,7 @@ version(tr("0.30.0_alpha9"))
ui->infoEdit->setFont(font);
ui->parserMessagesListWidget->setFont(font);
ui->finderMessagesListWidget->setFont(font);
ui->fitMessagesListWidget->setFont(font);
ui->fitTableWidget->setFont(font);
ui->structureTreeView->setFont(font);
searchDialog->ui->guidEdit->setFont(font);
@ -143,6 +144,8 @@ void UEFITool::init()
connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
connect(ui->fitMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
connect(ui->fitMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
}
void UEFITool::populateUi(const QModelIndex &current)
@ -662,8 +665,11 @@ void UEFITool::openImageFile(QString path)
// Parse FIT
//!TODO: expand and chek errors
result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf());
if (!result)
showFitMessages();
if (!result) {
showFitTable();
}
// Enable search ...
if (ffsFinder)
@ -686,6 +692,8 @@ void UEFITool::copyMessage()
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 1) // Search tab
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab
clipboard->setText(ui->fitMessagesListWidget->currentItem()->text());
}
void UEFITool::copyAllMessages()
@ -702,6 +710,11 @@ void UEFITool::copyAllMessages()
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text);
}
else if (ui->messagesTabWidget->currentIndex() == 2) { // FIT tab
for (INT32 i = 0; i < ui->fitMessagesListWidget->count(); i++)
text.append(ui->fitMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text);
}
}
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
@ -768,6 +781,22 @@ void UEFITool::showFinderMessages()
ui->finderMessagesListWidget->scrollToBottom();
}
void UEFITool::showFitMessages()
{
ui->fitMessagesListWidget->clear();
if (!fitParser)
return;
QVector<QPair<QString, QModelIndex> > messages = fitParser->getMessages();
QPair<QString, QModelIndex> msg;
foreach(msg, messages) {
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
}
ui->messagesTabWidget->setCurrentIndex(2);
ui->fitMessagesListWidget->scrollToBottom();
}
void UEFITool::scrollTreeView(QListWidgetItem* item)
{
MessageListItem* messageItem = static_cast<MessageListItem*>(item);
@ -862,9 +891,9 @@ void UEFITool::showFitTable()
// Set up the FIT table
ui->fitTableWidget->clear();
ui->fitTableWidget->setRowCount(fitTable.length());
ui->fitTableWidget->setColumnCount(6);
ui->fitTableWidget->setColumnCount(5);
//ui->fitTableWidget->verticalHeader()->setVisible(false);
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum") << tr("Remark"));
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum"));
ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
@ -872,7 +901,7 @@ void UEFITool::showFitTable()
// Add all data to the table widget
for (INT32 i = 0; i < fitTable.length(); i++) {
for (UINT8 j = 0; j < 6; j++) {
for (UINT8 j = 0; j < 5; j++) {
ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j]));
}
}

View File

@ -119,6 +119,7 @@ private:
void readSettings();
void showParserMessages();
void showFinderMessages();
void showFitMessages();
void showFitTable();
};

View File

@ -142,7 +142,7 @@
</widget>
<widget class="QTabWidget" name="messagesTabWidget">
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="parserTab">
<attribute name="title">
@ -223,7 +223,17 @@
<number>5</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTableWidget" name="fitTableWidget"/>
<widget class="QListWidget" name="fitMessagesListWidget">
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>

View File

@ -99,7 +99,7 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
capsuleHeaderSize = capsuleHeader->HeaderSize;
QByteArray header = buffer.left(capsuleHeaderSize);
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
QString name = tr("UEFI capsule");
QString name = tr("Toshiba capsule");
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
.arg(guidToQString(capsuleHeader->CapsuleGuid))
.hexarg(buffer.size()).arg(buffer.size())
@ -417,7 +417,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
if (descriptorVersion == 1) {
const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase);
info += tr("\nRegion access settings:");
info += tr("\nBIOS:%1h %2h ME:%3h %4h GbE:%5h %6h")
info += tr("\nBIOS: %1h %2h ME: %3h %4h\nGbE: %5h %6h")
.hexarg2(masterSection->BiosRead, 2)
.hexarg2(masterSection->BiosWrite, 2)
.hexarg2(masterSection->MeRead, 2)
@ -563,7 +563,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
// Add tree item
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
}
// Check if the last VTF is found
@ -902,7 +902,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
}
//Parse bodies
// Parse bodies
for (int i = 0; i < model->rowCount(index); i++) {
QModelIndex current = index.child(i, 0);
switch (model->type(current)) {
@ -1040,7 +1040,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
QByteArray body = volume.mid(headerSize);
QString name = guidToQString(volumeHeader->FileSystemGuid);
QString info = tr("ZeroVector:\n%1 %2 %3 %4 %5 %6 %7 %8\n%9 %10 %11 %12 %13 %14 %15 %16\nFileSystem GUID: %17\nFull size: %18h (%19)\n"
"Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26")
"Header size: %20h (%21)\nBody size: %22h (%23)\nRevision: %24\nAttributes: %25h\nErase polarity: %26\nChecksum: %27h, %28")
.hexarg2(volumeHeader->ZeroVector[0], 2).hexarg2(volumeHeader->ZeroVector[1], 2).hexarg2(volumeHeader->ZeroVector[2], 2).hexarg2(volumeHeader->ZeroVector[3], 2)
.hexarg2(volumeHeader->ZeroVector[4], 2).hexarg2(volumeHeader->ZeroVector[5], 2).hexarg2(volumeHeader->ZeroVector[6], 2).hexarg2(volumeHeader->ZeroVector[7], 2)
.hexarg2(volumeHeader->ZeroVector[8], 2).hexarg2(volumeHeader->ZeroVector[9], 2).hexarg2(volumeHeader->ZeroVector[10], 2).hexarg2(volumeHeader->ZeroVector[11], 2)
@ -1051,7 +1051,9 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
.hexarg(volumeSize - headerSize).arg(volumeSize - headerSize)
.arg(volumeHeader->Revision)
.hexarg2(volumeHeader->Attributes, 8)
.arg(emptyByte ? "1" : "0");
.arg(emptyByte ? "1" : "0")
.hexarg2(volumeHeader->Checksum, 4)
.arg(msgInvalidChecksum ? tr("invalid") : tr("valid"));
// Extended header present
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
@ -1415,14 +1417,18 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
else
name = tr("Pad-file");
info = tr("File GUID: %1\nType: %2h\nAttributes: %3h\nFull size: %4h (%5)\nHeader size: %6h (%7)\nBody size: %8h (%9)\nState: %10h")
info = tr("File GUID: %1\nType: %2h\nAttributes: %3h\nFull size: %4h (%5)\nHeader size: %6h (%7)\nBody size: %8h (%9)\nState: %10h\nHeader checksum: %11h, %12\nData checksum: %13h, %14")
.arg(guidToQString(fileHeader->Name))
.hexarg2(fileHeader->Type, 2)
.hexarg2(fileHeader->Attributes, 2)
.hexarg(header.size() + body.size()).arg(header.size() + body.size())
.hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size())
.hexarg2(fileHeader->State, 2);
.hexarg2(fileHeader->State, 2)
.hexarg2(fileHeader->IntegrityCheck.Checksum.Header, 2)
.arg(msgInvalidHeaderChecksum ? tr("invalid") : tr("valid"))
.hexarg2(fileHeader->IntegrityCheck.Checksum.File, 2)
.arg(msgInvalidDataChecksum ? tr("invalid") : tr("valid"));
// Check if the file is a Volume Top File
QString text;
@ -2111,11 +2117,12 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
QByteArray body = model->body(index);
UINT32 crc = crc32(0, (const UINT8*)body.constData(), body.size());
// Check stored CRC32
if (crc == *(const UINT32*)(model->header(index).constData() + sizeof(EFI_GUID_DEFINED_SECTION))) {
info += tr("\nChecksum: valid");
UINT32 stored = *(const UINT32*)(model->header(index).constData() + sizeof(EFI_GUID_DEFINED_SECTION));
if (crc == stored) {
info += tr("\nChecksum %1h: valid").hexarg2(stored, 8);
}
else {
info += tr("\nChecksum: invalid");
info += tr("\nChecksum %1h: invalid").hexarg2(stored, 8);
msg(tr("parseGuidedSectionBody: GUID defined section with invalid CRC32"), index);
}
}

View File

@ -23,6 +23,21 @@ FitParser::~FitParser()
{
}
void FitParser::msg(const QString & message, const QModelIndex & index)
{
messagesVector.push_back(QPair<QString, QModelIndex>(message, index));
}
QVector<QPair<QString, QModelIndex> > FitParser::getMessages() const
{
return messagesVector;
}
void FitParser::clearMessages()
{
messagesVector.clear();
}
STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIndex)
{
// Check sanity
@ -53,7 +68,6 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
model->setParsingData(fitIndex, parsingDataToQByteArray(pdata));
// Special case of FIT header
QString remark;
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset);
// Check FIT checksum, if present
@ -62,19 +76,15 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
// Calculate FIT entry checksum
UINT8 calculated = calculateChecksum8((const UINT8*)fitHeader, fitSize);
if (calculated) {
remark.append(tr("Invalid FIT table checksum, "));
msg(tr("Invalid FIT table checksum"), fitIndex);
}
}
// Check fit header type
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) {
remark.append(tr("Invalid FIT header type, "));
msg(tr("Invalid FIT header type"), fitIndex);
}
// Remove the last ", " from remark string, if needed
if (!remark.isEmpty())
remark = remark.left(remark.length() - 2);
// Add FIT header to fitTable
QVector<QString> currentStrings;
currentStrings += tr("_FIT_ ");
@ -82,19 +92,18 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
currentStrings += tr("%1").hexarg2(fitHeader->Version, 4);
currentStrings += fitEntryTypeToQString(fitHeader->Type);
currentStrings += tr("%1").hexarg2(fitHeader->Checksum, 2);
currentStrings += remark;
fitTable.append(currentStrings);
// Process all other entries
bool modifiedImageMayNotWork = false;
for (UINT32 i = 1; i < fitHeader->Size; i++) {
currentStrings.clear();
remark.clear();
const FIT_ENTRY* currentEntry = fitHeader + i;
// Check entry type
switch (currentEntry->Type & 0x7F) {
case FIT_TYPE_HEADER:
remark.append(tr("Second FIT header found, the table is damaged"));
msg(tr("Second FIT header found, the table is damaged"), fitIndex);
break;
case FIT_TYPE_EMPTY:
@ -109,7 +118,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
case FIT_TYPE_AC_KEY_MANIFEST:
case FIT_TYPE_AC_BOOT_POLICY:
default:
remark.append(tr("Modified image may not work"));
modifiedImageMayNotWork = true;
break;
}
@ -119,10 +128,12 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
currentStrings += tr("%1").hexarg2(currentEntry->Version, 4);
currentStrings += fitEntryTypeToQString(currentEntry->Type);
currentStrings += tr("%1").hexarg2(currentEntry->Checksum, 2);
currentStrings += remark;
fitTable.append(currentStrings);
}
if (modifiedImageMayNotWork)
msg(tr("Opened image may not work after any modification"));
return ERR_SUCCESS;
}
@ -170,8 +181,11 @@ STATUS FitParser::findFitRecursive(const QModelIndex & index, QModelIndex & foun
if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) {
found = index;
fitOffset = offset;
msg(tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found);
return ERR_SUCCESS;
}
else
msg(tr("FIT table candidate found, but not referenced from LastVtf"), found);
}
return ERR_SUCCESS;

View File

@ -36,16 +36,25 @@ public:
FitParser(TreeModel* treeModel, QObject *parent = 0);
~FitParser();
// Returns messages
QVector<QPair<QString, QModelIndex> > getMessages() const;
// Clears messages
void clearMessages();
STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf);
QVector<QVector<QString> > getFitTable() const { return fitTable; }
private:
TreeModel *model;
QVector<QPair<QString, QModelIndex> > messagesVector;
QModelIndex lastVtf;
QVector<QVector<QString> > fitTable;
STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset);
QString fitEntryTypeToQString(UINT8 type);
// Message helper
void msg(const QString & message, const QModelIndex &index = QModelIndex());
};
#endif