Version 0.13.0

Bugs solved:
- wrong file dialog on extracting raw file body
- replacing body of compressed section removes compression
- Volume Top File can be moved from the end of it's volume
This commit is contained in:
Nikolaj Schlej 2013-12-28 17:02:26 +01:00
parent 862fc6b242
commit 146c539dd8
4 changed files with 76 additions and 27 deletions

View File

@ -47,7 +47,7 @@ void FfsEngine::msg(const QString & message, const QModelIndex index)
messageItems.enqueue(MessageListItem(message, NULL, 0, index)); messageItems.enqueue(MessageListItem(message, NULL, 0, index));
} }
QQueue<MessageListItem> FfsEngine::messages() QQueue<MessageListItem> FfsEngine::messages() const
{ {
return messageItems; return messageItems;
} }
@ -89,14 +89,14 @@ bool FfsEngine::hasIntersection(const UINT32 begin1, const UINT32 end1, const UI
} }
// Firmware image parsing // Firmware image parsing
UINT8 FfsEngine::parseInputFile(const QByteArray & buffer) UINT8 FfsEngine::parseInputFile(const QByteArray & buffer)
{ {
UINT32 capsuleHeaderSize = 0; UINT32 capsuleHeaderSize = 0;
FLASH_DESCRIPTOR_HEADER* descriptorHeader = NULL; FLASH_DESCRIPTOR_HEADER* descriptorHeader = NULL;
QModelIndex index; QModelIndex index;
QByteArray flashImage; QByteArray flashImage;
// Check buffer size to be more or equal then sizeof(EFI_CAPSULE_HEADER) // Check buffer size to be more then or equal to sizeof(EFI_CAPSULE_HEADER)
if ((UINT32) buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) if ((UINT32) buffer.size() <= sizeof(EFI_CAPSULE_HEADER))
{ {
msg(tr("parseInputFile: Input file is smaller then minimum size of %1 bytes").arg(sizeof(EFI_CAPSULE_HEADER))); msg(tr("parseInputFile: Input file is smaller then minimum size of %1 bytes").arg(sizeof(EFI_CAPSULE_HEADER)));
@ -169,7 +169,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & flashImage, QModelIndex & in
//FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection; //FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection;
// Store the beginning of descriptor as descriptor base address // Store the beginning of descriptor as descriptor base address
UINT8* descriptor = (UINT8*) flashImage.constData(); UINT8* descriptor = (UINT8*) flashImage.constData();
UINT32 descriptorBegin = 0; UINT32 descriptorBegin = 0;
UINT32 descriptorEnd = FLASH_DESCRIPTOR_SIZE; UINT32 descriptorEnd = FLASH_DESCRIPTOR_SIZE;
@ -446,9 +446,9 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
UINT32 prevVolumeOffset; UINT32 prevVolumeOffset;
UINT8 result; UINT8 result;
result = findNextVolume(bios, 0, prevVolumeOffset); result = findNextVolume(bios, 0, prevVolumeOffset);
if (result) { if (result)
return result; return result;
}
// First volume is not at the beginning of BIOS space // First volume is not at the beginning of BIOS space
QString name; QString name;
@ -632,9 +632,9 @@ UINT8 FfsEngine::getVolumeSize(const QByteArray & bios, UINT32 volumeOffset, UIN
EFI_FV_BLOCK_MAP_ENTRY* entry = (EFI_FV_BLOCK_MAP_ENTRY*) (bios.constData() + volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER)); EFI_FV_BLOCK_MAP_ENTRY* entry = (EFI_FV_BLOCK_MAP_ENTRY*) (bios.constData() + volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
volumeSize = 0; volumeSize = 0;
while(entry->NumBlocks != 0 && entry->Length != 0) { while(entry->NumBlocks != 0 && entry->Length != 0) {
if ((void*) entry > bios.constData() + bios.size()) { if ((void*) entry > bios.constData() + bios.size())
return ERR_INVALID_VOLUME; return ERR_INVALID_VOLUME;
}
volumeSize += entry->NumBlocks * entry->Length; volumeSize += entry->NumBlocks * entry->Length;
entry += 1; entry += 1;
} }
@ -1227,10 +1227,9 @@ UINT8 FfsEngine::create(const QModelIndex & index, const UINT8 type, const QByte
fileHeader->IntegrityCheck.Checksum.Header = calculateChecksum8((UINT8*) fileHeader, sizeof(EFI_FFS_FILE_HEADER) - 1); fileHeader->IntegrityCheck.Checksum.Header = calculateChecksum8((UINT8*) fileHeader, sizeof(EFI_FFS_FILE_HEADER) - 1);
// Recalculate data checksum, if needed // Recalculate data checksum, if needed
if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM)
fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*) body.constData(), body.size()); fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*) body.constData(), body.size());
} else if (revision == 1)
else if (revision == 1)
fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
else else
fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2; fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2;
@ -1259,8 +1258,7 @@ UINT8 FfsEngine::create(const QModelIndex & index, const UINT8 type, const QByte
// Set action // Set action
treeModel->setItemAction(action, fileIndex); treeModel->setItemAction(action, fileIndex);
}
}
else if (type == TreeItem::Section) { else if (type == TreeItem::Section) {
if (parentItem->type() != TreeItem::File && parentItem->type() != TreeItem::Section) if (parentItem->type() != TreeItem::File && parentItem->type() != TreeItem::Section)
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
@ -1410,8 +1408,9 @@ UINT8 FfsEngine::replace(const QModelIndex & index, const QByteArray & object, c
headerSize = sizeOfSectionHeaderOfType(commonHeader->Type); headerSize = sizeOfSectionHeaderOfType(commonHeader->Type);
result = create(index, TreeItem::Section, object.left(headerSize), object.right(object.size() - headerSize), CREATE_MODE_AFTER, TreeItem::Replace); result = create(index, TreeItem::Section, object.left(headerSize), object.right(object.size() - headerSize), CREATE_MODE_AFTER, TreeItem::Replace);
} }
else if (mode == REPLACE_MODE_BODY) else if (mode == REPLACE_MODE_BODY) {
result = create(index, TreeItem::Section, parentItem->header(), object, CREATE_MODE_AFTER, TreeItem::Replace); result = create(index, TreeItem::Section, parentItem->header(), object, CREATE_MODE_AFTER, TreeItem::Replace, parentItem->compression());
}
else else
return ERR_NOT_IMPLEMENTED; return ERR_NOT_IMPLEMENTED;
} }
@ -1937,13 +1936,26 @@ UINT8 FfsEngine::reconstruct(const QModelIndex & index, QQueue<QByteArray> & que
} }
// Remove all pad files, they will be recreated later // Remove all pad files, they will be recreated later
foreach(const QByteArray & child, childrenQueue) foreach(const QByteArray & child, childrenQueue) {
{
EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) child.constData(); EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) child.constData();
if (fileHeader->Type == EFI_FV_FILETYPE_PAD) if (fileHeader->Type == EFI_FV_FILETYPE_PAD)
childrenQueue.removeAll(child); childrenQueue.removeAll(child);
} }
// Ensure that Volume Top File is the last file of the volume
foreach(const QByteArray & child, childrenQueue) {
// Check for VTF
if (child.left(sizeof(EFI_GUID)) == EFI_FFS_VOLUME_TOP_FILE_GUID) {
// If VTF is not the last file in the volume
if(childrenQueue.indexOf(child) + 1 != childrenQueue.length()) {
// Remove VTF and add it to the end of the volume
QByteArray vtf = child;
childrenQueue.removeAll(child);
childrenQueue.append(vtf);
}
}
}
// Get volume size // Get volume size
UINT32 volumeSize; UINT32 volumeSize;
result = getVolumeSize(header, 0, volumeSize); result = getVolumeSize(header, 0, volumeSize);

View File

@ -38,7 +38,7 @@ public:
TreeModel* model() const; TreeModel* model() const;
// Returns message items queue // Returns message items queue
QQueue<MessageListItem> messages(); QQueue<MessageListItem> messages() const;
// Clears message items queue // Clears message items queue
void clearMessages(); void clearMessages();
@ -86,6 +86,7 @@ public:
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; TreeItem *rootItem;
TreeModel *treeModel; TreeModel *treeModel;

View File

@ -384,7 +384,7 @@ void UEFITool::extract(const UINT8 mode)
else if (item->subtype() == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) else if (item->subtype() == 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 (item->subtype() == EFI_SECTION_RAW)
path = QFileDialog::getOpenFileName(this, tr("Select 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 (*.*)");
} }

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>834</width> <width>800</width>
<height>499</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -20,7 +20,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>UEFITool 0.12.0</string> <string>UEFITool 0.13.0</string>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="centralWidget">
<property name="sizePolicy"> <property name="sizePolicy">
@ -33,7 +33,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -53,7 +62,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
@ -91,7 +109,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
@ -121,7 +148,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number> <number>5</number>
</property> </property>
<item> <item>
@ -139,7 +175,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>834</width> <width>800</width>
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>