diff --git a/basetypes.h b/basetypes.h index 883f2b2..f261a57 100644 --- a/basetypes.h +++ b/basetypes.h @@ -93,11 +93,11 @@ typedef uint16_t CHAR16; #define COMPRESSION_ALGORITHM_LZMA 4 #define COMPRESSION_ALGORITHM_IMLZMA 5 -// Item add modes -#define ADD_MODE_APPEND 0 -#define ADD_MODE_PREPEND 1 -#define ADD_MODE_INSERT_BEFORE 2 -#define ADD_MODE_INSERT_AFTER 3 +// Item insert modes +#define INSERT_MODE_APPEND 0 +#define INSERT_MODE_PREPEND 1 +#define INSERT_MODE_BEFORE 2 +#define INSERT_MODE_AFTER 3 // EFI GUID typedef struct{ diff --git a/ffsengine.cpp b/ffsengine.cpp index 970afc4..765f4b1 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -372,11 +372,10 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent) UINT32 prevVolumeOffset; UINT8 result; result = findNextVolume(bios, 0, prevVolumeOffset); - if (result == ERR_VOLUMES_NOT_FOUND) - { - //msg(tr("No volumes found in BIOS space")); + if (result == ERR_VOLUMES_NOT_FOUND) { return result; } + // First volume is not at the beginning of BIOS space QString name; QString info; @@ -514,8 +513,21 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent) prevVolumeSize = volumeSize; result = findNextVolume(bios, volumeOffset + prevVolumeSize, volumeOffset); - if (result == ERR_VOLUMES_NOT_FOUND) + if (result) { + UINT32 endPaddingSize = bios.size() - prevVolumeOffset - prevVolumeSize; + // Padding at the end of BIOS space + if (endPaddingSize > 0) { + QByteArray padding = bios.right(endPaddingSize); + // Get info + name = tr("Padding"); + info = tr("Size: %2") + .arg(padding.size(), 8, 16, QChar('0')); + // Add tree item + treeModel->addItem(TreeItem::Padding, 0, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, parent); + } break; + } + } return ERR_SUCCESS; @@ -576,7 +588,7 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par msg(tr("parseBios: Volume header checksum is invalid")); } - // Check for presence of extended header, only if header revision is not 1 + // Check for presence of extended header, only if header revision is greater then 1 UINT32 headerSize; if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) { 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 QByteArray body = volume.mid(headerSize, volumeHeader->FvLength - headerSize); QModelIndex index = treeModel->addItem(TreeItem::Volume, 0, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, parent, mode); + // Do not parse volumes with unknown FS + if (!parseCurrentVolume) + return ERR_SUCCESS; + // Search for and parse all files UINT32 fileOffset = headerSize; UINT32 fileSize; UINT8 result; + QQueue files; + while (true) { result = getFileSize(volume, fileOffset, fileSize); if (result) @@ -616,9 +634,9 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par QByteArray file = volume.mid(fileOffset, fileSize); QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER)); - // We are now at empty space in the end of volume + // If we are at empty space in the end of volume if (header.count(empty) == header.size()) - break; + break; // Exit from loop // Check file alignment EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) header.constData(); @@ -628,6 +646,14 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, const QModelIndex & par msg(tr("parseVolume: %1, unaligned file").arg(guidToQString(fileHeader->Name))); } + // Check file GUID + if (fileHeader->Type != EFI_FV_FILETYPE_PAD && files.indexOf(header.left(sizeof(EFI_GUID))) != -1) + msg(tr("%1: file with duplicate GUID").arg(guidToQString(fileHeader->Name))); + + // Add file GUID to queue + files.enqueue(header.left(sizeof(EFI_GUID))); + + // Parse file result = parseFile(file, volumeHeader->Revision, empty, index); if (result) 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 result = parseBios(body, index); if (result && result != ERR_VOLUMES_NOT_FOUND) msg(tr("parseVolume: Parse file as BIOS failed (%1)").arg(result)); + return ERR_SUCCESS; } + // Parse sections - else { - result = parseSections(body, revision, empty, index); - if (result) - return result; - } + result = parseSections(body, revision, empty, index); + if (result) + return result; return ERR_SUCCESS; } @@ -959,11 +985,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision, case EFI_SECTION_PIC: case EFI_SECTION_TE: case EFI_SECTION_VERSION: - case EFI_SECTION_COMPATIBILITY16: case EFI_SECTION_FREEFORM_SUBTYPE_GUID: case EFI_SECTION_DXE_DEPEX: case EFI_SECTION_PEI_DEPEX: case EFI_SECTION_SMM_DEPEX: + case EFI_SECTION_COMPATIBILITY16: headerSize = sizeOfSectionHeaderOfType(sectionHeader->Type); header = section.left(headerSize); body = section.mid(headerSize, sectionSize - headerSize); @@ -997,6 +1023,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision, case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: header = section.left(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION)); body = section.mid(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION), sectionSize - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION)); + // Get info info = tr("Type: %1\nSize: %2") .arg(sectionHeader->Type, 2, 16, QChar('0')) @@ -1015,6 +1042,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, const UINT8 revision, case EFI_SECTION_RAW: header = section.left(sizeof(EFI_RAW_SECTION)); body = section.mid(sizeof(EFI_RAW_SECTION), sectionSize - sizeof(EFI_RAW_SECTION)); + // Get info info = tr("Type: %1\nSize: %2") .arg(sectionHeader->Type, 2, 16, QChar('0')) @@ -1055,22 +1083,21 @@ UINT8 FfsEngine::insert(const QModelIndex & index, const QByteArray & object, co // Only files and sections can now be inserted if (type == TreeItem::File) { QModelIndex parent; - if (mode == ADD_MODE_APPEND || mode == ADD_MODE_PREPEND) - parent = index; - else + if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER) parent = index.parent(); + else + parent = index; // Parent type must be volume TreeItem * parentItem = static_cast(parent.internalPointer()); if (parentItem->type() != TreeItem::Volume) { - msg(tr("insertInto: file can't be inserted into something that is not volume")); + msg(tr("insert: file can't be inserted into something that is not volume")); return ERR_INVALID_VOLUME; } EFI_FIRMWARE_VOLUME_HEADER* header = (EFI_FIRMWARE_VOLUME_HEADER*) parentItem->header().constData(); // Parse file - //!TODO: add check for same GUIDs UINT8 result = parseFile(object, header->Revision, header->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00', index, mode); if (result) return result; @@ -1081,7 +1108,40 @@ UINT8 FfsEngine::insert(const QModelIndex & index, const QByteArray & object, co } else if (type == TreeItem::Section) { - return ERR_NOT_IMPLEMENTED; + QModelIndex parent; + if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER) + parent = index.parent(); + else + parent = index; + + // Parent type must be file or encapsulation section + TreeItem * parentItem = static_cast(parent.internalPointer()); + if (parentItem->type() == TreeItem::File || (parentItem->type() == TreeItem::Section && + (parentItem->subtype() == EFI_SECTION_COMPRESSION || + parentItem->subtype() == EFI_SECTION_GUID_DEFINED || + parentItem->subtype() == EFI_SECTION_DISPOSABLE))) { + QModelIndex volumeIndex = findParentOfType(TreeItem::Volume, parent); + if (!volumeIndex.isValid()) { + msg(tr("insert: Parent volume not found")); + return ERR_INVALID_VOLUME; + } + + TreeItem * volumeItem = static_cast(volumeIndex.internalPointer()); + EFI_FIRMWARE_VOLUME_HEADER* header = (EFI_FIRMWARE_VOLUME_HEADER*) volumeItem->header().constData(); + + // Parse section + UINT8 result = parseSection(object, header->Revision, header->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00', index, mode); + if (result) + return result; + + // Set reconstruct action for all parents + for (;parent.isValid(); parent = parent.parent()) + treeModel->setItemAction(TreeItem::Reconstruct, parent); + } + else { + msg(tr("insert: section can't be inserted into something that is not file or encapsulation section")); + return ERR_INVALID_FILE; + } } else return ERR_NOT_IMPLEMENTED; diff --git a/ffsengine.h b/ffsengine.h index 7a8e529..3bad5ae 100644 --- a/ffsengine.h +++ b/ffsengine.h @@ -44,15 +44,15 @@ public: UINT8 parseBios(const QByteArray & bios, const QModelIndex & parent = QModelIndex()); UINT8 findNextVolume(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); UINT8 getVolumeSize(const QByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize); - UINT8 parseVolume(const QByteArray & volume, const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND); + UINT8 parseVolume(const QByteArray & volume, const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND); UINT8 getFileSize(const QByteArray & volume, const UINT32 fileOffset, UINT32 & fileSize); - UINT8 parseFile(const QByteArray & file, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND); + UINT8 parseFile(const QByteArray & file, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND); UINT8 getSectionSize(const QByteArray & file, const UINT32 sectionOffset, UINT32 & sectionSize); UINT8 parseSections(const QByteArray & body, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex()); - UINT8 parseSection(const QByteArray & section, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = ADD_MODE_APPEND); + UINT8 parseSection(const QByteArray & section, const UINT8 revision, const char empty = '\xFF', const QModelIndex & parent = QModelIndex(), const UINT8 mode = INSERT_MODE_APPEND); // Compression routines - UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedSection, UINT8 * algorithm = NULL); + UINT8 decompress(const QByteArray & compressed, const UINT8 compressionType, QByteArray & decompressedData, UINT8 * algorithm = NULL); UINT8 compress(const QByteArray & data, const UINT8 algorithm, QByteArray & compressedData); // Construction routines @@ -74,7 +74,7 @@ public: bool isOfType(UINT8 type, const QModelIndex & index) const; bool isOfSubtype(UINT8 subtype, const QModelIndex & index) const; QModelIndex findParentOfType(UINT8 type, const QModelIndex& index) const; - + // Will be refactored later bool isCompressedFile(const QModelIndex & index) const; QByteArray decompressFile(const QModelIndex & index) const; diff --git a/treeitem.cpp b/treeitem.cpp index 0ec2238..d4125e7 100644 --- a/treeitem.cpp +++ b/treeitem.cpp @@ -162,14 +162,14 @@ QVariant TreeItem::data(int column) const { switch(column) { - case 0: //Action + case 0: //Name + return itemName; + case 1: //Action if (itemAction == TreeItem::Remove) return "X"; if (itemAction == TreeItem::Reconstruct) return "R"; return QVariant(); - case 1: //Name - return itemName; case 2: //Type return itemTypeName; case 3: //Subtype diff --git a/treemodel.cpp b/treemodel.cpp index d7c33ce..58e4947 100644 --- a/treemodel.cpp +++ b/treemodel.cpp @@ -162,31 +162,31 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype, const UINT parentItem = rootItem; else { - if (mode == ADD_MODE_APPEND || mode == ADD_MODE_PREPEND) { - parentItem = static_cast(index.internalPointer()); - parentColumn = index.column(); - } - else { + if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_AFTER) { item = static_cast(index.internalPointer()); parentItem = item->parent(); parentColumn = index.parent().column(); } + else { + parentItem = static_cast(index.internalPointer()); + parentColumn = index.column(); + } } TreeItem *newItem = new TreeItem(type, subtype, compression, name, text, info, header, body, parentItem); - if (mode == ADD_MODE_APPEND) { + if (mode == INSERT_MODE_APPEND) { emit layoutAboutToBeChanged(); parentItem->appendChild(newItem); } - else if (mode == ADD_MODE_PREPEND) { + else if (mode == INSERT_MODE_PREPEND) { emit layoutAboutToBeChanged(); parentItem->prependChild(newItem); } - else if (mode == ADD_MODE_INSERT_BEFORE) { + else if (mode == INSERT_MODE_BEFORE) { emit layoutAboutToBeChanged(); parentItem->insertChildBefore(item, newItem); } - else if (mode == ADD_MODE_INSERT_AFTER) { + else if (mode == INSERT_MODE_AFTER) { emit layoutAboutToBeChanged(); parentItem->insertChildAfter(item, newItem); } diff --git a/treemodel.h b/treemodel.h index f1adfb5..4788ad6 100644 --- a/treemodel.h +++ b/treemodel.h @@ -48,7 +48,7 @@ public: QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0, const UINT8 compression = COMPRESSION_ALGORITHM_NONE, const QString & name = QString(), const QString & text = QString(), const QString & info = QString(), const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QModelIndex & index = QModelIndex(), - const UINT8 mode = ADD_MODE_APPEND); + const UINT8 mode = INSERT_MODE_APPEND); private: TreeItem *rootItem; diff --git a/uefitool.cpp b/uefitool.cpp index cd1df49..452781c 100644 --- a/uefitool.cpp +++ b/uefitool.cpp @@ -32,10 +32,11 @@ UEFITool::UEFITool(QWidget *parent) : connect(ui->actionReplace, SIGNAL(triggered()), this, SLOT(replace())); connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove())); connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile())); + // Enable Drag-and-Drop actions this->setAcceptDrops(true); - // Initialise non-persistent data + // Initialize non-persistent data init(); } @@ -71,11 +72,12 @@ void UEFITool::init() connect(ui->structureTreeView, SIGNAL(expanded(const QModelIndex &)), this, SLOT(resizeTreeViewColums(void))); connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(populateUi(const QModelIndex &))); + + resizeTreeViewColums(); } -void UEFITool::populateUi(const QModelIndex ¤t/*, const QModelIndex &previous*/) +void UEFITool::populateUi(const QModelIndex ¤t) { - //!TODO: make widget currentIndex = current; ui->infoEdit->setPlainText(current.data(Qt::UserRole).toString()); ui->actionExtract->setDisabled(ffsEngine->hasEmptyBody(current) && ffsEngine->hasEmptyHeader(current)); @@ -84,10 +86,14 @@ void UEFITool::populateUi(const QModelIndex ¤t/*, const QModelIndex &previ ui->actionRemove->setEnabled(ffsEngine->isOfType(TreeItem::Volume, current) || ffsEngine->isOfType(TreeItem::File, current) || ffsEngine->isOfType(TreeItem::Section, current)); - ui->actionInsertInto->setEnabled(ffsEngine->isOfType(TreeItem::Volume, current)); - ui->actionInsertBefore->setEnabled(ffsEngine->isOfType(TreeItem::File, current)); - ui->actionInsertAfter->setEnabled(ffsEngine->isOfType(TreeItem::File, current)); - ui->actionReplace->setEnabled(ffsEngine->isOfType(TreeItem::File, current)); + ui->actionInsertInto->setEnabled(ffsEngine->isOfType(TreeItem::Volume, current) + || ffsEngine->isOfType(TreeItem::File, current) + || ffsEngine->isOfType(TreeItem::Section, current)); + ui->actionInsertBefore->setEnabled(ffsEngine->isOfType(TreeItem::File, current) + || ffsEngine->isOfType(TreeItem::Section, current)); + ui->actionInsertAfter->setEnabled(ffsEngine->isOfType(TreeItem::File, current) + || ffsEngine->isOfType(TreeItem::Section, current)); + //ui->actionReplace->setEnabled(ffsEngine->isOfType(TreeItem::File, current)); } void UEFITool::remove() @@ -98,109 +104,87 @@ void UEFITool::remove() } else ui->actionSaveImageFile->setEnabled(true); - resizeTreeViewColums(); + + resizeTreeViewColums(); +} +void UEFITool::insert(const UINT8 mode) +{ + QString path; + TreeItem* item = static_cast(currentIndex.internalPointer()); + + UINT8 type; + UINT8 objectType; + if (mode == INSERT_MODE_BEFORE || mode == INSERT_MODE_BEFORE) + type = item->parent()->type(); + else + type = item->type(); + + switch (type) { + case TreeItem::Volume: + path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS file (*.ffs *.bin);;All files (*.*)"); + objectType = TreeItem::File; + break; + case TreeItem::File: + case TreeItem::Section: + path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"),".","Section file (*.sec *.bin);;All files (*.*)"); + objectType = TreeItem::Section; + break; + default: + return; + } + + QFileInfo fileInfo = QFileInfo(path); + if (!fileInfo.exists()) + { + ui->statusBar->showMessage(tr("Please select existing file")); + return; + } + + QFile inputFile; + inputFile.setFileName(path); + + if (!inputFile.open(QFile::ReadOnly)) + { + ui->statusBar->showMessage(tr("Can't open file for reading")); + return; + } + + QByteArray buffer = inputFile.readAll(); + inputFile.close(); + + UINT8 result = ffsEngine->insert(currentIndex, buffer, objectType, mode); + if (result) + ui->statusBar->showMessage(tr("File can't be inserted (%1)").arg(result)); + else + ui->actionSaveImageFile->setEnabled(true); + + resizeTreeViewColums(); } void UEFITool::insertInto() { - QString path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS file (*.ffs *.bin);;All files (*.*)"); - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) - { - ui->statusBar->showMessage(tr("Please select existing FFS file")); - return; - } - - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) - { - ui->statusBar->showMessage(tr("Can't open file for reading")); - return; - } - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - UINT8 result = ffsEngine->insert(currentIndex, buffer, TreeItem::File, ADD_MODE_PREPEND); - if (result) - ui->statusBar->showMessage(tr("FFS file can't be inserted (%1)").arg(result)); - else - ui->actionSaveImageFile->setEnabled(true); - resizeTreeViewColums(); + insert(INSERT_MODE_PREPEND); } void UEFITool::insertBefore() { - QString path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS file (*.ffs *.bin);;All files (*.*)"); - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) - { - ui->statusBar->showMessage(tr("Please select existing FFS file")); - return; - } - - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) - { - ui->statusBar->showMessage(tr("Can't open file for reading")); - return; - } - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - UINT8 result = ffsEngine->insert(currentIndex, buffer, TreeItem::File, ADD_MODE_INSERT_BEFORE); - if (result) - ui->statusBar->showMessage(tr("FFS file can't be inserted (%1)").arg(result)); - else - ui->actionSaveImageFile->setEnabled(true); - resizeTreeViewColums(); + insert(INSERT_MODE_BEFORE); } void UEFITool::insertAfter() { - QString path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"),".","FFS file (*.ffs *.bin);;All files (*.*)"); - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) - { - ui->statusBar->showMessage(tr("Please select existing FFS file")); - return; - } - - QFile inputFile; - inputFile.setFileName(path); - - if (!inputFile.open(QFile::ReadOnly)) - { - ui->statusBar->showMessage(tr("Can't open file for reading")); - return; - } - - QByteArray buffer = inputFile.readAll(); - inputFile.close(); - - UINT8 result = ffsEngine->insert(currentIndex, buffer, TreeItem::File, ADD_MODE_INSERT_AFTER); - if (result) - ui->statusBar->showMessage(tr("FFS file can't be inserted (%1)").arg(result)); - else - ui->actionSaveImageFile->setEnabled(true); - resizeTreeViewColums(); + insert(INSERT_MODE_AFTER); } void UEFITool::replace() { - remove(); - insertAfter(); + } void UEFITool::saveImageFile() { - QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"),".","BIOS image file (*.rom *.bin *.cap *.fd *.fwh);;All files (*.*)"); + QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"),".","BIOS image file (*.rom *.bin *.cap *.fd *.wph *.efi);;All files (*.*)"); QFile outputFile; outputFile.setFileName(path); @@ -219,6 +203,7 @@ void UEFITool::saveImageFile() return; } + outputFile.resize(0); outputFile.write(reconstructed); outputFile.close(); ui->statusBar->showMessage(tr("Reconstructed image written")); @@ -243,7 +228,7 @@ void UEFITool::openImageFile(QString path) QFileInfo fileInfo = QFileInfo(path); if (!fileInfo.exists()) { - ui->statusBar->showMessage(tr("Please select existing BIOS image file")); + ui->statusBar->showMessage(tr("Please select existing file")); return; } @@ -262,7 +247,7 @@ void UEFITool::openImageFile(QString path) init(); UINT8 result = ffsEngine->parseInputFile(buffer); if (result) - ui->statusBar->showMessage(tr("Opened file can't be parsed as UEFI image (%1)").arg(result)); + ui->statusBar->showMessage(tr("Opened file can't be parsed (%1)").arg(result)); else ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName())); @@ -279,66 +264,49 @@ void UEFITool::extract() outputFile.setFileName(path); if (!outputFile.open(QFile::WriteOnly)) { - ui->statusBar->showMessage(tr("Can't open file for writing. Check file permissions.")); + ui->statusBar->showMessage(tr("Can't open file for rewriting")); return; } + outputFile.resize(0); outputFile.write(ffsEngine->header(currentIndex) + ffsEngine->body(currentIndex)); outputFile.close(); } void UEFITool::extractBody() { - QString path = QFileDialog::getSaveFileName(this, tr("Save selected item without header to binary file"),".","Binary files (*.bin);;All files (*.*)"); + QString path = QFileDialog::getSaveFileName(this, tr("Save selected item without header to file"),".","Binary files (*.bin);;All files (*.*)"); QFile outputFile; outputFile.setFileName(path); if (!outputFile.open(QFile::WriteOnly)) { - ui->statusBar->showMessage(tr("Can't open file for writing. Check file permissions.")); + ui->statusBar->showMessage(tr("Can't open file for rewriting")); return; } + outputFile.resize(0); outputFile.write(ffsEngine->body(currentIndex)); outputFile.close(); } void UEFITool::extractUncompressed() { - QString path = QFileDialog::getSaveFileName(this, tr("Save selected FFS file as uncompressed to binary file"),".","FFS files (*.ffs);;All files (*.*)"); + QString path = QFileDialog::getSaveFileName(this, tr("Save selected FFS file as uncompressed to file"),".","FFS files (*.ffs);;All files (*.*)"); QFile outputFile; outputFile.setFileName(path); if (!outputFile.open(QFile::WriteOnly)) { - ui->statusBar->showMessage(tr("Can't open file for writing. Check file permissions.")); + ui->statusBar->showMessage(tr("Can't open file for rewriting")); return; } - + + outputFile.resize(0); outputFile.write(ffsEngine->decompressFile(currentIndex)); outputFile.close(); } -/*void UEFITool::saveImageFile() -{ - QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"),".","BIOS image file (*.rom *.bin *.cap *.fd *.fwh);;All files (*.*)"); - - QFileInfo fileInfo = QFileInfo(path); - if (!fileInfo.exists()) - { - ui->statusBar->showMessage(tr("Please select existing BIOS image file.")); - return; - } - - QFile outputFile; - outputFile.setFileName(path); - if (!outputFile.open(QFile::ReadWrite)) - { - ui->statusBar->showMessage(tr("Can't open file for writing. Check file permissions.")); - return; - } -}*/ - void UEFITool::dragEnterEvent(QDragEnterEvent* event) { if (event->mimeData()->hasFormat("text/uri-list")) diff --git a/uefitool.h b/uefitool.h index 85df7e8..dda0aae 100644 --- a/uefitool.h +++ b/uefitool.h @@ -52,6 +52,7 @@ private slots: void extract(); void extractBody(); void extractUncompressed(); + void insert(const UINT8 mode); void insertInto(); void insertBefore(); void insertAfter(); diff --git a/uefitool.ui b/uefitool.ui index a611da3..9d66126 100644 --- a/uefitool.ui +++ b/uefitool.ui @@ -20,7 +20,7 @@ true - UEFITool 0.4.0 + UEFITool 0.5.0 @@ -203,7 +203,7 @@ toolBar - TopToolBarArea + LeftToolBarArea false