diff --git a/ffsengine.cpp b/ffsengine.cpp index c8208fc..9587ea7 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -47,7 +47,7 @@ void FfsEngine::msg(const QString & message, const QModelIndex index) messageItems.enqueue(MessageListItem(message, NULL, 0, index)); } -QQueue FfsEngine::messages() +QQueue FfsEngine::messages() const { return messageItems; } @@ -89,14 +89,14 @@ bool FfsEngine::hasIntersection(const UINT32 begin1, const UINT32 end1, const UI } // Firmware image parsing -UINT8 FfsEngine::parseInputFile(const QByteArray & buffer) +UINT8 FfsEngine::parseInputFile(const QByteArray & buffer) { UINT32 capsuleHeaderSize = 0; FLASH_DESCRIPTOR_HEADER* descriptorHeader = NULL; QModelIndex index; 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)) { 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; // Store the beginning of descriptor as descriptor base address - UINT8* descriptor = (UINT8*) flashImage.constData(); + UINT8* descriptor = (UINT8*) flashImage.constData(); UINT32 descriptorBegin = 0; UINT32 descriptorEnd = FLASH_DESCRIPTOR_SIZE; @@ -446,9 +446,9 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent) UINT32 prevVolumeOffset; UINT8 result; result = findNextVolume(bios, 0, prevVolumeOffset); - if (result) { + if (result) return result; - } + // First volume is not at the beginning of BIOS space 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)); volumeSize = 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; - } + volumeSize += entry->NumBlocks * entry->Length; 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); // 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()); - } - else if (revision == 1) + else if (revision == 1) fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; else fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2; @@ -1259,8 +1258,7 @@ UINT8 FfsEngine::create(const QModelIndex & index, const UINT8 type, const QByte // Set action treeModel->setItemAction(action, fileIndex); - - } + } else if (type == TreeItem::Section) { if (parentItem->type() != TreeItem::File && parentItem->type() != TreeItem::Section) return ERR_INVALID_SECTION; @@ -1410,8 +1408,9 @@ UINT8 FfsEngine::replace(const QModelIndex & index, const QByteArray & object, c headerSize = sizeOfSectionHeaderOfType(commonHeader->Type); result = create(index, TreeItem::Section, object.left(headerSize), object.right(object.size() - headerSize), CREATE_MODE_AFTER, TreeItem::Replace); } - else if (mode == REPLACE_MODE_BODY) - result = create(index, TreeItem::Section, parentItem->header(), object, CREATE_MODE_AFTER, TreeItem::Replace); + else if (mode == REPLACE_MODE_BODY) { + result = create(index, TreeItem::Section, parentItem->header(), object, CREATE_MODE_AFTER, TreeItem::Replace, parentItem->compression()); + } else return ERR_NOT_IMPLEMENTED; } @@ -1937,13 +1936,26 @@ UINT8 FfsEngine::reconstruct(const QModelIndex & index, QQueue & que } // 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(); if (fileHeader->Type == EFI_FV_FILETYPE_PAD) 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 UINT32 volumeSize; result = getVolumeSize(header, 0, volumeSize); diff --git a/ffsengine.h b/ffsengine.h index 6f2ba57..8390975 100644 --- a/ffsengine.h +++ b/ffsengine.h @@ -38,7 +38,7 @@ public: TreeModel* model() const; // Returns message items queue - QQueue messages(); + QQueue messages() const; // Clears message items queue void clearMessages(); @@ -86,6 +86,7 @@ public: UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode); 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); + private: TreeItem *rootItem; TreeModel *treeModel; diff --git a/uefitool.cpp b/uefitool.cpp index bfeb9c2..f0141b8 100644 --- a/uefitool.cpp +++ b/uefitool.cpp @@ -384,7 +384,7 @@ void UEFITool::extract(const UINT8 mode) 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 (*.*)"); 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 path = QFileDialog::getSaveFileName(this, tr("Save section body to file"),".","Binary files (*.bin);;All files (*.*)"); } diff --git a/uefitool.ui b/uefitool.ui index 41257b9..d74901d 100644 --- a/uefitool.ui +++ b/uefitool.ui @@ -6,8 +6,8 @@ 0 0 - 834 - 499 + 800 + 500 @@ -20,7 +20,7 @@ true - UEFITool 0.12.0 + UEFITool 0.13.0 @@ -33,7 +33,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -53,7 +62,16 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 @@ -91,7 +109,16 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 @@ -121,7 +148,16 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 @@ -139,7 +175,7 @@ 0 0 - 834 + 800 21