From a4a40ec3299f653bacb697b49e7bd252a9b78f8a Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Tue, 28 Jan 2014 14:48:04 +0100 Subject: [PATCH] Version 0.16.6 - fixed another bug in reconstructing tailed files - fixed creation of empty output files - statusBar messages replaced by messageBoxes --- descriptor.h | 9 ++++++- ffsengine.cpp | 71 ++++++++++++++++++++++++++++++++++++--------------- uefitool.cpp | 59 ++++++++++++++++++++++-------------------- uefitool.ui | 67 +++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 152 insertions(+), 54 deletions(-) diff --git a/descriptor.h b/descriptor.h index 546d8d2..df27933 100644 --- a/descriptor.h +++ b/descriptor.h @@ -53,7 +53,7 @@ typedef struct { // Component section -// Flash parameters dword structure +// Flash parameters DWORD structure typedef struct { UINT8 FirstChipDensity : 3; UINT8 SecondChipDensity : 3; @@ -126,6 +126,13 @@ typedef struct { UINT8 GbeWrite; } FLASH_DESCRIPTOR_MASTER_SECTION; +// Region access bits in master section +#define FLASH_DESCRIPTOR_REGION_ACCESS_DESC 0x01 +#define FLASH_DESCRIPTOR_REGION_ACCESS_BIOS 0x02 +#define FLASH_DESCRIPTOR_REGION_ACCESS_ME 0x04 +#define FLASH_DESCRIPTOR_REGION_ACCESS_GBE 0x08 +#define FLASH_DESCRIPTOR_REGION_ACCESS_PDR 0x10 + //!TODO: Describe PCH and PROC straps sections, as well as ICC and DMI tables // Base address of descriptor upper map diff --git a/ffsengine.cpp b/ffsengine.cpp index 557e633..fe4c065 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -148,7 +148,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in { FLASH_DESCRIPTOR_MAP* descriptorMap; FLASH_DESCRIPTOR_REGION_SECTION* regionSection; - //FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection; + FLASH_DESCRIPTOR_MASTER_SECTION* masterSection; // Store the beginning of descriptor as descriptor base address UINT8* descriptor = (UINT8*) intelImage.constData(); @@ -162,9 +162,9 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in } // Parse descriptor map - descriptorMap = (FLASH_DESCRIPTOR_MAP*) (descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); - regionSection = (FLASH_DESCRIPTOR_REGION_SECTION*) calculateAddress8(descriptor, descriptorMap->RegionBase); - //componentSection = (FLASH_DESCRIPTOR_COMPONENT_SECTION*) calculateAddress8(descriptor, descriptorMap->ComponentBase); + descriptorMap = (FLASH_DESCRIPTOR_MAP*) (descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); + regionSection = (FLASH_DESCRIPTOR_REGION_SECTION*) calculateAddress8(descriptor, descriptorMap->RegionBase); + masterSection = (FLASH_DESCRIPTOR_MASTER_SECTION*) calculateAddress8(descriptor, descriptorMap->MasterBase); // GbE region QByteArray gbe; @@ -282,11 +282,11 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in QVector offsets; if (regionSection->GbeLimit) { offsets.append(gbeBegin); - info += tr("\nGbE region offset: %1").arg(gbeBegin, 8, 16, QChar('0')); + info += tr("\nGbE region offset: %1").arg(gbeBegin, 8, 16, QChar('0')); } if (regionSection->MeLimit) { offsets.append(meBegin); - info += tr("\nME region offset: %1").arg(meBegin, 8, 16, QChar('0')); + info += tr("\nME region offset: %1").arg(meBegin, 8, 16, QChar('0')); } if (regionSection->BiosLimit) { offsets.append(biosBegin); @@ -294,9 +294,38 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in } if (regionSection->PdrLimit) { offsets.append(pdrBegin); - info += tr("\nPDR region offset: %1").arg(pdrBegin, 8, 16, QChar('0')); + info += tr("\nPDR region offset: %1").arg(pdrBegin, 8, 16, QChar('0')); } + // Region access settings + info += tr("\nRegion access settings:"); + info += tr("\nBIOS %1%2 ME %2%3 GbE %4%5") + .arg(masterSection->BiosRead, 2, 16, QChar('0')) + .arg(masterSection->BiosWrite, 2, 16, QChar('0')) + .arg(masterSection->MeRead, 2, 16, QChar('0')) + .arg(masterSection->MeWrite, 2, 16, QChar('0')) + .arg(masterSection->GbeRead, 2, 16, QChar('0')) + .arg(masterSection->GbeWrite, 2, 16, QChar('0')); + + // BIOS access table + info += tr("\nBIOS access table:"); + info += tr("\n Read Write"); + info += tr("\nDesc %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_DESC ? "Yes " : "No "); + info += tr("\nBIOS Yes Yes"); + info += tr("\nME %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_ME ? "Yes " : "No "); + info += tr("\nGbE %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_GBE ? "Yes " : "No "); + info += tr("\nPDR %1 %2") + .arg(masterSection->BiosRead & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No ") + .arg(masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); + + // VSCC table + // Add descriptor tree item model->addItem(Region, DescriptorRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), body, QByteArray(), index); @@ -2213,11 +2242,11 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, reconstructed.clear(); return ERR_SUCCESS; } - else if (model->action(index) == Insert || - model->action(index) == Replace || - model->action(index) == Rebuild) { + else if (model->action(index) == Insert || + model->action(index) == Replace || + model->action(index) == Rebuild) { QByteArray header = model->header(index); - EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*) header.data(); + EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*)header.data(); // Check erase polarity if (erasePolarity == ERASE_POLARITY_UNKNOWN) { @@ -2275,13 +2304,13 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, // File contains raw data, must be parsed as region if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) { result = reconstructRegion(index, reconstructed); - if (result) - return result; + if (result) + return result; } // File contains sections else { UINT32 offset = 0; - + for (int i = 0; i < model->rowCount(index); i++) { // Align to 4 byte boundary UINT8 alignment = offset % 4; @@ -2292,7 +2321,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, } // Calculate section base - UINT32 sectionBase = base ? base + sizeof(EFI_FFS_FILE_HEADER) + offset : 0; + UINT32 sectionBase = base ? base + sizeof(EFI_FFS_FILE_HEADER) + offset : 0; // Reconstruct section QByteArray section; @@ -2320,7 +2349,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, // Recalculate header checksum fileHeader->IntegrityCheck.Checksum.Header = 0; fileHeader->IntegrityCheck.Checksum.File = 0; - 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); } // Use current file body @@ -2329,7 +2358,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, // Recalculate data checksum, if needed if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM) { - fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*) reconstructed.constData(), reconstructed.size()); + fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*)reconstructed.constData(), reconstructed.size()); } else if (revision == 1) fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; @@ -2337,9 +2366,11 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision, fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2; // Append tail, if needed - if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) - reconstructed.append(~fileHeader->IntegrityCheck.TailReference); - + if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) { + UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header; + UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File; + reconstructed.append(ht).append(ft); + } // Set file state state = EFI_FILE_DATA_VALID | EFI_FILE_HEADER_VALID | EFI_FILE_HEADER_CONSTRUCTION; if (erasePolarity == ERASE_POLARITY_TRUE) diff --git a/uefitool.cpp b/uefitool.cpp index 568ec80..f393ee1 100644 --- a/uefitool.cpp +++ b/uefitool.cpp @@ -213,7 +213,7 @@ void UEFITool::insert(const UINT8 mode) inputFile.setFileName(path); if (!inputFile.open(QFile::ReadOnly)) { - ui->statusBar->showMessage(tr("Can't open file for reading")); + QMessageBox::critical(this, tr("Insertion failed"), tr("Can't open output file for reading"), QMessageBox::Ok); return; } @@ -222,7 +222,7 @@ void UEFITool::insert(const UINT8 mode) UINT8 result = ffsEngine->insert(index, buffer, mode); if (result) - ui->statusBar->showMessage(tr("File can't be inserted (%1)").arg(result)); + QMessageBox::critical(this, tr("Insertion failed"), tr("Error code: %d").arg(result), QMessageBox::Ok); else ui->actionSaveImageFile->setEnabled(true); } @@ -305,7 +305,7 @@ void UEFITool::replace(const UINT8 mode) inputFile.setFileName(path); if (!inputFile.open(QFile::ReadOnly)) { - ui->statusBar->showMessage(tr("Can't open file for reading")); + QMessageBox::critical(this, tr("Replacing failed"), tr("Can't open input file for reading"), QMessageBox::Ok); return; } @@ -314,7 +314,7 @@ void UEFITool::replace(const UINT8 mode) UINT8 result = ffsEngine->replace(index, buffer, mode); if (result) - ui->statusBar->showMessage(tr("File can't be replaced (%1)").arg(result)); + QMessageBox::critical(this, tr("Replacing failed"), tr("Error code: %d").arg(result), QMessageBox::Ok); else ui->actionSaveImageFile->setEnabled(true); } @@ -380,7 +380,7 @@ void UEFITool::extract(const UINT8 mode) break; case Section: { if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) - path = QFileDialog::getSaveFileName(this, tr("Save encapsulated section body to FFS body file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); + path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"),".","FFS file body files (*.fbd *.bin);;All files (*.*)"); else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"),".","Volume files (*.vol *.bin);;All files (*.*)"); else if (model->subtype(index) == EFI_SECTION_RAW) @@ -396,22 +396,23 @@ void UEFITool::extract(const UINT8 mode) else path = QFileDialog::getSaveFileName(this, tr("Save object 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 rewriting")); + QByteArray extracted; + UINT8 result = ffsEngine->extract(index, extracted, mode); + if (result) { + QMessageBox::critical(this, tr("Extraction failed"), tr("Error code: %d").arg(result), QMessageBox::Ok); return; } - QByteArray extracted; - UINT8 result = ffsEngine->extract(index, extracted, mode); - if (result) - ui->statusBar->showMessage(tr("File can't be extracted (%1)").arg(result)); - else { - outputFile.resize(0); - outputFile.write(extracted); - outputFile.close(); + QFile outputFile; + outputFile.setFileName(path); + if (!outputFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Extraction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok); + return; } + outputFile.resize(0); + outputFile.write(extracted); + outputFile.close(); + } void UEFITool::about() @@ -440,25 +441,29 @@ void UEFITool::saveImageFile() { QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"),".","BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi);;All files (*.*)"); - QFile outputFile; - outputFile.setFileName(path); - if (!outputFile.open(QFile::WriteOnly)) { - ui->statusBar->showMessage(tr("Can't open file for writing")); - return; - } + QByteArray reconstructed; UINT8 result = ffsEngine->reconstructImageFile(reconstructed); showMessages(); if (result) { - ui->statusBar->showMessage(tr("Reconstruction failed (%1)").arg(result)); + QMessageBox::critical(this, tr("Image reconstruction failed"), tr("Error code: %d").arg(result), QMessageBox::Ok); + return; + } + + QFile outputFile; + outputFile.setFileName(path); + if (!outputFile.open(QFile::WriteOnly)) { + QMessageBox::critical(this, tr("Image reconstruction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok); return; } outputFile.resize(0); outputFile.write(reconstructed); outputFile.close(); - ui->statusBar->showMessage(tr("Reconstructed image written")); + if (QMessageBox::information(this, tr("Image reconstruction successful"), tr("Open reconstructed file?"), QMessageBox::Yes, QMessageBox::No) + == QMessageBox::Yes) + openImageFile(path); } void UEFITool::openImageFile() @@ -479,7 +484,7 @@ void UEFITool::openImageFile(QString path) inputFile.setFileName(path); if (!inputFile.open(QFile::ReadOnly)) { - ui->statusBar->showMessage(tr("Can't open file for reading")); + QMessageBox::critical(this, tr("Image parsing failed"), tr("Can't open input file for reading"), QMessageBox::Ok); return; } @@ -490,7 +495,7 @@ void UEFITool::openImageFile(QString path) UINT8 result = ffsEngine->parseImageFile(buffer); showMessages(); if (result) - ui->statusBar->showMessage(tr("Opened file can't be parsed (%1)").arg(result)); + QMessageBox::critical(this, tr("Image parsing failed"), tr("Error code: %d").arg(result), QMessageBox::Ok); else ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName())); diff --git a/uefitool.ui b/uefitool.ui index 294fb24..644d2f7 100644 --- a/uefitool.ui +++ b/uefitool.ui @@ -20,7 +20,7 @@ true - UEFITool 0.16.5 + UEFITool 0.16.6 @@ -33,7 +33,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -53,7 +62,16 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 @@ -64,6 +82,12 @@ 0 + + + Consolas + 9 + + 10 @@ -91,11 +115,26 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 + + + Consolas + 9 + + false @@ -121,11 +160,27 @@ 0 - + + 5 + + + 5 + + + 5 + + 5 - + + + + Consolas + 9 + + +