Skip to content

Commit 6ff5119

Browse files
committed
Version 0.5.0
- Minor bugs corrected - Implemented section insertion - Replace temporary removed
1 parent 4a61fcd commit 6ff5119

File tree

9 files changed

+170
-141
lines changed

9 files changed

+170
-141
lines changed

basetypes.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ typedef uint16_t CHAR16;
9393
#define COMPRESSION_ALGORITHM_LZMA 4
9494
#define COMPRESSION_ALGORITHM_IMLZMA 5
9595

96-
// Item add modes
97-
#define ADD_MODE_APPEND 0
98-
#define ADD_MODE_PREPEND 1
99-
#define ADD_MODE_INSERT_BEFORE 2
100-
#define ADD_MODE_INSERT_AFTER 3
96+
// Item insert modes
97+
#define INSERT_MODE_APPEND 0
98+
#define INSERT_MODE_PREPEND 1
99+
#define INSERT_MODE_BEFORE 2
100+
#define INSERT_MODE_AFTER 3
101101

102102
// EFI GUID
103103
typedef struct{

ffsengine.cpp

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,10 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
372372
UINT32 prevVolumeOffset;
373373
UINT8 result;
374374
result = findNextVolume(bios, 0, prevVolumeOffset);
375-
if (result == ERR_VOLUMES_NOT_FOUND)
376-
{
377-
//msg(tr("No volumes found in BIOS space"));
375+
if (result == ERR_VOLUMES_NOT_FOUND) {
378376
return result;
379377
}
378+
380379
// First volume is not at the beginning of BIOS space
381380
QString name;
382381
QString info;
@@ -514,8 +513,21 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
514513
prevVolumeSize = volumeSize;
515514

516515
result = findNextVolume(bios, volumeOffset + prevVolumeSize, volumeOffset);
517-
if (result == ERR_VOLUMES_NOT_FOUND)
516+
if (result) {
517+
UINT32 endPaddingSize = bios.size() - prevVolumeOffset - prevVolumeSize;
518+
// Padding at the end of BIOS space
519+
if (endPaddingSize > 0) {
520+
QByteArray padding = bios.right(endPaddingSize);
521+
// Get info
522+
name = tr("Padding");
523+
info = tr("Size: %2")
524+
.arg(padding.size(), 8, 16, QChar('0'));
525+
// Add tree item
526+
treeModel->addItem(TreeItem::Padding, 0, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, parent);
527+
}
518528
break;
529+
}
530+
519531
}
520532

521533
return ERR_SUCCESS;
@@ -576,7 +588,7 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par
576588
msg(tr("parseBios: Volume header checksum is invalid"));
577589
}
578590

579-
// Check for presence of extended header, only if header revision is not 1
591+
// Check for presence of extended header, only if header revision is greater then 1
580592
UINT32 headerSize;
581593
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
582594
EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*) ((UINT8*) volumeHeader + volumeHeader->ExtHeaderOffset);
@@ -598,10 +610,16 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par
598610
QByteArray body = volume.mid(headerSize, volumeHeader->FvLength - headerSize);
599611
QModelIndex index = treeModel->addItem(TreeItem::Volume, 0, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, parent, mode);
600612

613+
// Do not parse volumes with unknown FS
614+
if (!parseCurrentVolume)
615+
return ERR_SUCCESS;
616+
601617
// Search for and parse all files
602618
UINT32 fileOffset = headerSize;
603619
UINT32 fileSize;
604620
UINT8 result;
621+
QQueue<QByteArray> files;
622+
605623
while (true) {
606624
result = getFileSize(volume, fileOffset, fileSize);
607625
if (result)
@@ -616,9 +634,9 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par
616634
QByteArray file = volume.mid(fileOffset, fileSize);
617635
QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER));
618636

619-
// We are now at empty space in the end of volume
637+
// If we are at empty space in the end of volume
620638
if (header.count(empty) == header.size())
621-
break;
639+
break; // Exit from loop
622640

623641
// Check file alignment
624642
EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) header.constData();
@@ -628,6 +646,14 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par
628646
msg(tr("parseVolume: %1, unaligned file").arg(guidToQString(fileHeader->Name)));
629647
}
630648

649+
// Check file GUID
650+
if (fileHeader->Type != EFI_FV_FILETYPE_PAD && files.indexOf(header.left(sizeof(EFI_GUID))) != -1)
651+
msg(tr("%1: file with duplicate GUID").arg(guidToQString(fileHeader->Name)));
652+
653+
// Add file GUID to queue
654+
files.enqueue(header.left(sizeof(EFI_GUID)));
655+
656+
// Parse file
631657
result = parseFile(file, volumeHeader->Revision, empty, index);
632658
if (result)
633659
msg(tr("parseVolume: Parse FFS file failed (%1)").arg(result));
@@ -790,13 +816,13 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, UINT8 revision, const char e
790816
result = parseBios(body, index);
791817
if (result && result != ERR_VOLUMES_NOT_FOUND)
792818
msg(tr("parseVolume: Parse file as BIOS failed (%1)").arg(result));
819+
return ERR_SUCCESS;
793820
}
821+
794822
// Parse sections
795-
else {
796-
result = parseSections(body, revision, empty, index);
797-
if (result)
798-
return result;
799-
}
823+
result = parseSections(body, revision, empty, index);
824+
if (result)
825+
return result;
800826

801827
return ERR_SUCCESS;
802828
}
@@ -959,11 +985,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision,
959985
case EFI_SECTION_PIC:
960986
case EFI_SECTION_TE:
961987
case EFI_SECTION_VERSION:
962-
case EFI_SECTION_COMPATIBILITY16:
963988
case EFI_SECTION_FREEFORM_SUBTYPE_GUID:
964989
case EFI_SECTION_DXE_DEPEX:
965990
case EFI_SECTION_PEI_DEPEX:
966991
case EFI_SECTION_SMM_DEPEX:
992+
case EFI_SECTION_COMPATIBILITY16:
967993
headerSize = sizeOfSectionHeaderOfType(sectionHeader->Type);
968994
header = section.left(headerSize);
969995
body = section.mid(headerSize, sectionSize - headerSize);
@@ -997,6 +1023,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision,
9971023
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
9981024
header = section.left(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
9991025
body = section.mid(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION), sectionSize - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
1026+
10001027
// Get info
10011028
info = tr("Type: %1\nSize: %2")
10021029
.arg(sectionHeader->Type, 2, 16, QChar('0'))
@@ -1015,6 +1042,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision,
10151042
case EFI_SECTION_RAW:
10161043
header = section.left(sizeof(EFI_RAW_SECTION));
10171044
body = section.mid(sizeof(EFI_RAW_SECTION), sectionSize - sizeof(EFI_RAW_SECTION));
1045+
10181046
// Get info
10191047
info = tr("Type: %1\nSize: %2")
10201048
.arg(sectionHeader->Type, 2, 16, QChar('0'))
@@ -1055,22 +1083,21 @@ UINT8 FfsEngine::insert(const QModelIndex & index, const QByteArray & object, co
10551083
// Only files and sections can now be inserted
10561084
if (type == TreeItem::File) {
10571085
QModelIndex parent;
1058-
if (mode == ADD_MODE_APPEND || mode == ADD_MODE_PREPEND)
1059-
parent = index;
1060-
else
1086+
if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER)
10611087
parent = index.parent();
1088+
else
1089+
parent = index;
10621090

10631091
// Parent type must be volume
10641092
TreeItem * parentItem = static_cast<TreeItem*>(parent.internalPointer());
10651093
if (parentItem->type() != TreeItem::Volume) {
1066-
msg(tr("insertInto: file can't be inserted into something that is not volume"));
1094+
msg(tr("insert: file can't be inserted into something that is not volume"));
10671095
return ERR_INVALID_VOLUME;
10681096
}
10691097

10701098
EFI_FIRMWARE_VOLUME_HEADER* header = (EFI_FIRMWARE_VOLUME_HEADER*) parentItem->header().constData();
10711099

10721100
// Parse file
1073-
//!TODO: add check for same GUIDs
10741101
UINT8 result = parseFile(object, header->Revision, header->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00', index, mode);
10751102
if (result)
10761103
return result;
@@ -1081,7 +1108,40 @@ UINT8 FfsEngine::insert(const QModelIndex & index, const QByteArray & object, co
10811108

10821109
}
10831110
else if (type == TreeItem::Section) {
1084-
return ERR_NOT_IMPLEMENTED;
1111+
QModelIndex parent;
1112+
if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER)
1113+
parent = index.parent();
1114+
else
1115+
parent = index;
1116+
1117+
// Parent type must be file or encapsulation section
1118+
TreeItem * parentItem = static_cast<TreeItem*>(parent.internalPointer());
1119+
if (parentItem->type() == TreeItem::File || (parentItem->type() == TreeItem::Section &&
1120+
(parentItem->subtype() == EFI_SECTION_COMPRESSION ||
1121+
parentItem->subtype() == EFI_SECTION_GUID_DEFINED ||
1122+
parentItem->subtype() == EFI_SECTION_DISPOSABLE))) {
1123+
QModelIndex volumeIndex = findParentOfType(TreeItem::Volume, parent);
1124+
if (!volumeIndex.isValid()) {
1125+
msg(tr("insert: Parent volume not found"));
1126+
return ERR_INVALID_VOLUME;
1127+
}
1128+
1129+
TreeItem * volumeItem = static_cast<TreeItem*>(volumeIndex.internalPointer());
1130+
EFI_FIRMWARE_VOLUME_HEADER* header = (EFI_FIRMWARE_VOLUME_HEADER*) volumeItem->header().constData();
1131+
1132+
// Parse section
1133+
UINT8 result = parseSection(object, header->Revision, header->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00', index, mode);
1134+
if (result)
1135+
return result;
1136+
1137+
// Set reconstruct action for all parents
1138+
for (;parent.isValid(); parent = parent.parent())
1139+
treeModel->setItemAction(TreeItem::Reconstruct, parent);
1140+
}
1141+
else {
1142+
msg(tr("insert: section can't be inserted into something that is not file or encapsulation section"));
1143+
return ERR_INVALID_FILE;
1144+
}
10851145
}
10861146
else
10871147
return ERR_NOT_IMPLEMENTED;

ffsengine.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ class FfsEngine : public QObject
4444
UINT8 parseBios(const QByteArray & bios, const QModelIndex & parent = QModelIndex());
4545
UINT8 findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
4646
UINT8 getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize);
47-
UINT8 parseVolume(const QByteArray & volume, const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND);
47+
UINT8 parseVolume(const QByteArray & volume, const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND);
4848
UINT8 getFileSize(const QByteArray & volume, const UINT32 fileOffset, UINT32 & fileSize);
49-
UINT8 parseFile(const QByteArray & file, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND);
49+
UINT8 parseFile(const QByteArray & file, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND);
5050
UINT8 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, UINT32 & sectionSize);
5151
UINT8 parseSections(const QByteArray & body, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex());
52-
UINT8 parseSection(const QByteArray & section, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND);
52+
UINT8 parseSection(const QByteArray & section, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND);
5353

5454
// Compression routines
55-
UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedSection, UINT8 * algorithm = NULL);
55+
UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedData, UINT8 * algorithm = NULL);
5656
UINT8 compress(const QByteArray & data, const UINT8 algorithm, QByteArray & compressedData);
5757

5858
// Construction routines
@@ -74,7 +74,7 @@ class FfsEngine : public QObject
7474
bool isOfType(UINT8 type, const QModelIndex & index) const;
7575
bool isOfSubtype(UINT8 subtype, const QModelIndex & index) const;
7676
QModelIndex findParentOfType(UINT8 type, const QModelIndex& index) const;
77-
77+
7878
// Will be refactored later
7979
bool isCompressedFile(const QModelIndex & index) const;
8080
QByteArray decompressFile(const QModelIndex & index) const;

treeitem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ QVariant TreeItem::data(int column) const
162162
{
163163
switch(column)
164164
{
165-
case 0: //Action
165+
case 0: //Name
166+
return itemName;
167+
case 1: //Action
166168
if (itemAction == TreeItem::Remove)
167169
return "X";
168170
if (itemAction == TreeItem::Reconstruct)
169171
return "R";
170172
return QVariant();
171-
case 1: //Name
172-
return itemName;
173173
case 2: //Type
174174
return itemTypeName;
175175
case 3: //Subtype

treemodel.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,31 +162,31 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT
162162
parentItem = rootItem;
163163
else
164164
{
165-
if (mode == ADD_MODE_APPEND || mode == ADD_MODE_PREPEND) {
166-
parentItem = static_cast<TreeItem*>(index.internalPointer());
167-
parentColumn = index.column();
168-
}
169-
else {
165+
if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER) {
170166
item = static_cast<TreeItem*>(index.internalPointer());
171167
parentItem = item->parent();
172168
parentColumn = index.parent().column();
173169
}
170+
else {
171+
parentItem = static_cast<TreeItem*>(index.internalPointer());
172+
parentColumn = index.column();
173+
}
174174
}
175175

176176
TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, parentItem);
177-
if (mode == ADD_MODE_APPEND) {
177+
if (mode == INSERT_MODE_APPEND) {
178178
emit layoutAboutToBeChanged();
179179
parentItem->appendChild(newItem);
180180
}
181-
else if (mode == ADD_MODE_PREPEND) {
181+
else if (mode == INSERT_MODE_PREPEND) {
182182
emit layoutAboutToBeChanged();
183183
parentItem->prependChild(newItem);
184184
}
185-
else if (mode == ADD_MODE_INSERT_BEFORE) {
185+
else if (mode == INSERT_MODE_BEFORE) {
186186
emit layoutAboutToBeChanged();
187187
parentItem->insertChildBefore(item, newItem);
188188
}
189-
else if (mode == ADD_MODE_INSERT_AFTER) {
189+
else if (mode == INSERT_MODE_AFTER) {
190190
emit layoutAboutToBeChanged();
191191
parentItem->insertChildAfter(item, newItem);
192192
}

treemodel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class TreeModel : public QAbstractItemModel
4848
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE,
4949
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
5050
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QModelIndex & index = QModelIndex(),
51-
const UINT8 mode = ADD_MODE_APPEND);
51+
const UINT8 mode = INSERT_MODE_APPEND);
5252

5353
private:
5454
TreeItem *rootItem;

0 commit comments

Comments
 (0)