mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 17:38:22 +08:00
NE alpha11
- added sanity checks during volume header parsing - corrected various small FIT issues - corrected bogus "unaligned volume" messages during capsule files parsing
This commit is contained in:
parent
f6c429f00c
commit
9eed1e3fd4
@ -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_alpha10"))
|
version(tr("0.30.0_alpha11"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
@ -107,6 +107,8 @@ void UEFITool::init()
|
|||||||
ui->parserMessagesListWidget->clear();
|
ui->parserMessagesListWidget->clear();
|
||||||
ui->finderMessagesListWidget->clear();
|
ui->finderMessagesListWidget->clear();
|
||||||
ui->fitTableWidget->clear();
|
ui->fitTableWidget->clear();
|
||||||
|
ui->fitTableWidget->setRowCount(0);
|
||||||
|
ui->fitTableWidget->setColumnCount(0);
|
||||||
ui->infoEdit->clear();
|
ui->infoEdit->clear();
|
||||||
|
|
||||||
// Set window title
|
// Set window title
|
||||||
@ -261,11 +263,11 @@ void UEFITool::search()
|
|||||||
|
|
||||||
void UEFITool::rebuild()
|
void UEFITool::rebuild()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
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);*/
|
||||||
@ -273,11 +275,11 @@ void UEFITool::rebuild()
|
|||||||
|
|
||||||
void UEFITool::remove()
|
void UEFITool::remove()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->remove(index);
|
UINT8 result = ffsEngine->remove(index);
|
||||||
|
|
||||||
if (result == ERR_SUCCESS)
|
if (result == ERR_SUCCESS)
|
||||||
ui->actionSaveImageFile->setEnabled(true);*/
|
ui->actionSaveImageFile->setEnabled(true);*/
|
||||||
@ -285,7 +287,7 @@ void UEFITool::remove()
|
|||||||
|
|
||||||
void UEFITool::insert(const UINT8 mode)
|
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;
|
||||||
|
|
||||||
@ -329,7 +331,7 @@ void UEFITool::insert(const UINT8 mode)
|
|||||||
QByteArray buffer = inputFile.readAll();
|
QByteArray buffer = inputFile.readAll();
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|
||||||
/*UINT8 result = ffsEngine->insert(index, buffer, mode);
|
UINT8 result = ffsEngine->insert(index, buffer, mode);
|
||||||
if (result) {
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
||||||
return;
|
return;
|
||||||
@ -364,7 +366,7 @@ 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;
|
||||||
|
|
||||||
@ -444,7 +446,7 @@ 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 = ffsEngine->replace(index, buffer, mode);
|
||||||
if (result) {
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Replacing failed"), errorMessage(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Replacing failed"), errorMessage(result), QMessageBox::Ok);
|
||||||
return;
|
return;
|
||||||
@ -657,13 +659,14 @@ void UEFITool::openImageFile(QString path)
|
|||||||
|
|
||||||
UINT8 result = ffsParser->parseImageFile(buffer, model->index(0,0));
|
UINT8 result = ffsParser->parseImageFile(buffer, model->index(0,0));
|
||||||
showParserMessages();
|
showParserMessages();
|
||||||
if (result)
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToQString(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToQString(result), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
|
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
|
||||||
|
|
||||||
// Parse FIT
|
// Parse FIT
|
||||||
//!TODO: expand and chek errors
|
|
||||||
result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf());
|
result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf());
|
||||||
showFitMessages();
|
showFitMessages();
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -733,6 +736,10 @@ void UEFITool::clearMessages()
|
|||||||
ffsFinder->clearMessages();
|
ffsFinder->clearMessages();
|
||||||
ui->finderMessagesListWidget->clear();
|
ui->finderMessagesListWidget->clear();
|
||||||
}
|
}
|
||||||
|
else if (ui->messagesTabWidget->currentIndex() == 2) { // FIT tab
|
||||||
|
fitParser->clearMessages();
|
||||||
|
ui->fitMessagesListWidget->clear();
|
||||||
|
}
|
||||||
ui->actionMessagesCopy->setEnabled(false);
|
ui->actionMessagesCopy->setEnabled(false);
|
||||||
ui->actionMessagesCopyAll->setEnabled(false);
|
ui->actionMessagesCopyAll->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -793,7 +800,6 @@ void UEFITool::showFitMessages()
|
|||||||
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
|
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->messagesTabWidget->setCurrentIndex(2);
|
|
||||||
ui->fitMessagesListWidget->scrollToBottom();
|
ui->fitMessagesListWidget->scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="messagesTabWidget">
|
<widget class="QTabWidget" name="messagesTabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="parserTab">
|
<widget class="QWidget" name="parserTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -22,7 +22,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "fit.h"
|
#include "fit.h"
|
||||||
|
|
||||||
FfsParser::FfsParser(TreeModel* treeModel, QObject *parent)
|
FfsParser::FfsParser(TreeModel* treeModel, QObject *parent)
|
||||||
: QObject(parent), model(treeModel)
|
: QObject(parent), model(treeModel), capsuleOffsetFixup(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +61,9 @@ BOOLEAN FfsParser::hasIntersection(const UINT32 begin1, const UINT32 end1, const
|
|||||||
// Firmware image parsing functions
|
// Firmware image parsing functions
|
||||||
STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex & root)
|
STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex & root)
|
||||||
{
|
{
|
||||||
|
// Reset capsule offset fixeup value
|
||||||
|
capsuleOffsetFixup = 0;
|
||||||
|
|
||||||
// Check buffer size to be more then or equal to size of EFI_CAPSULE_HEADER
|
// Check buffer size to be more then or equal to size of EFI_CAPSULE_HEADER
|
||||||
if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) {
|
if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) {
|
||||||
msg(tr("parseImageFile: image file is smaller then minimum size of %1h (%2) bytes").hexarg(sizeof(EFI_CAPSULE_HEADER)).arg(sizeof(EFI_CAPSULE_HEADER)));
|
msg(tr("parseImageFile: image file is smaller then minimum size of %1h (%2) bytes").hexarg(sizeof(EFI_CAPSULE_HEADER)).arg(sizeof(EFI_CAPSULE_HEADER)));
|
||||||
@ -89,6 +92,9 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
|
capsuleOffsetFixup = capsuleHeader->HeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||||
}
|
}
|
||||||
@ -111,6 +117,9 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
|
capsuleOffsetFixup = capsuleHeader->HeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||||
}
|
}
|
||||||
@ -134,6 +143,9 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
|
capsuleOffsetFixup = capsuleHeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||||
|
|
||||||
@ -781,7 +793,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
STATUS result;
|
STATUS result;
|
||||||
UINT32 prevVolumeOffset;
|
UINT32 prevVolumeOffset;
|
||||||
|
|
||||||
result = findNextVolume(data, 0, prevVolumeOffset);
|
result = findNextVolume(index, data, 0, prevVolumeOffset);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -880,7 +892,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
// Go to next volume
|
// Go to next volume
|
||||||
prevVolumeOffset = volumeOffset;
|
prevVolumeOffset = volumeOffset;
|
||||||
prevVolumeSize = volumeSize;
|
prevVolumeSize = volumeSize;
|
||||||
result = findNextVolume(data, volumeOffset + prevVolumeSize, volumeOffset);
|
result = findNextVolume(index, data, volumeOffset + prevVolumeSize, volumeOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Padding at the end of BIOS space
|
// Padding at the end of BIOS space
|
||||||
@ -1001,7 +1013,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
// Acquire alignment
|
// Acquire alignment
|
||||||
alignment = (UINT32)pow(2.0, (int)(volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
|
alignment = (UINT32)pow(2.0, (int)(volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
|
||||||
// Check alignment
|
// Check alignment
|
||||||
if (!isUnknown && pdata.isOnFlash && ((pdata.offset + parentOffset) % alignment))
|
if (!isUnknown && pdata.isOnFlash && ((pdata.offset + parentOffset - capsuleOffsetFixup) % alignment))
|
||||||
msgUnaligned = true;
|
msgUnaligned = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1109,12 +1121,34 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS FfsParser::findNextVolume(const QByteArray & bios, UINT32 volumeOffset, UINT32 & nextVolumeOffset)
|
STATUS FfsParser::findNextVolume(const QModelIndex index, const QByteArray & bios, UINT32 volumeOffset, UINT32 & nextVolumeOffset)
|
||||||
{
|
{
|
||||||
int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset);
|
int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset);
|
||||||
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
|
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
|
||||||
return ERR_VOLUMES_NOT_FOUND;
|
return ERR_VOLUMES_NOT_FOUND;
|
||||||
|
|
||||||
|
// Check volume header to be sane
|
||||||
|
for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset + nextIndex + 1)) {
|
||||||
|
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET);
|
||||||
|
if (volumeHeader->FvLength >= 0xFFFFFFFFUL) {
|
||||||
|
msg(tr("findNextVolume: volume candidate skipped, has invalid FvLength %1h").hexarg2(volumeHeader->FvLength, 16), index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (volumeHeader->Reserved != 0xFF && volumeHeader->Reserved != 0x00) {
|
||||||
|
msg(tr("findNextVolume: volume candidate skipped, has invalid Reserved byte value %1").hexarg2(volumeHeader->Reserved, 2), index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) {
|
||||||
|
msg(tr("findNextVolume: volume candidate skipped, has invalid Revision byte value %1").hexarg2(volumeHeader->Revision, 2), index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// All checks passed, volume found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// No additional volumes found
|
||||||
|
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
|
||||||
|
return ERR_VOLUMES_NOT_FOUND;
|
||||||
|
|
||||||
nextVolumeOffset = nextIndex - EFI_FV_SIGNATURE_OFFSET;
|
nextVolumeOffset = nextIndex - EFI_FV_SIGNATURE_OFFSET;
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ private:
|
|||||||
TreeModel *model;
|
TreeModel *model;
|
||||||
QVector<QPair<QString, QModelIndex> > messagesVector;
|
QVector<QPair<QString, QModelIndex> > messagesVector;
|
||||||
QModelIndex lastVtf;
|
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);
|
||||||
@ -89,15 +90,13 @@ private:
|
|||||||
|
|
||||||
UINT8 getPaddingType(const QByteArray & padding);
|
UINT8 getPaddingType(const QByteArray & padding);
|
||||||
STATUS parseAprioriRawSection(const QByteArray & body, QString & parsed);
|
STATUS parseAprioriRawSection(const QByteArray & body, QString & parsed);
|
||||||
STATUS findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
STATUS findNextVolume(const QModelIndex index, const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
||||||
STATUS getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
STATUS getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
||||||
UINT32 getFileSize(const QByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
UINT32 getFileSize(const QByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
||||||
UINT32 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
UINT32 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
||||||
|
|
||||||
STATUS performSecondPass(const QModelIndex & index);
|
STATUS performSecondPass(const QModelIndex & index);
|
||||||
STATUS addMemoryAddressesRecursive(const QModelIndex & index, const UINT32 diff);
|
STATUS addMemoryAddressesRecursive(const QModelIndex & index, const UINT32 diff);
|
||||||
/*STATUS parseFit(const QModelIndex & index);
|
|
||||||
STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found);*/
|
|
||||||
|
|
||||||
// Internal operations
|
// Internal operations
|
||||||
BOOLEAN hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
|
BOOLEAN hasIntersection(const UINT32 begin1, const UINT32 end1, const UINT32 begin2, const UINT32 end2);
|
||||||
|
@ -184,8 +184,8 @@ STATUS FitParser::findFitRecursive(const QModelIndex & index, QModelIndex & foun
|
|||||||
msg(tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found);
|
msg(tr("Real FIT table found at physical address %1h").hexarg(fitAddress), found);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else if (model->rowCount(index) == 0) // Show messages only to leaf items
|
||||||
msg(tr("FIT table candidate found, but not referenced from LastVtf"), found);
|
msg(tr("FIT table candidate found, but not referenced from the last VTF"), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
Loading…
Reference in New Issue
Block a user