Version 0.16.6

- fixed another bug in reconstructing tailed files
- fixed creation of empty output files
- statusBar messages replaced by messageBoxes
This commit is contained in:
Nikolaj Schlej 2014-01-28 14:48:04 +01:00
parent 6c96a243d3
commit a4a40ec329
4 changed files with 152 additions and 54 deletions

View File

@ -53,7 +53,7 @@ typedef struct {
// Component section // Component section
// Flash parameters dword structure // Flash parameters DWORD structure
typedef struct { typedef struct {
UINT8 FirstChipDensity : 3; UINT8 FirstChipDensity : 3;
UINT8 SecondChipDensity : 3; UINT8 SecondChipDensity : 3;
@ -126,6 +126,13 @@ typedef struct {
UINT8 GbeWrite; UINT8 GbeWrite;
} FLASH_DESCRIPTOR_MASTER_SECTION; } 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 //!TODO: Describe PCH and PROC straps sections, as well as ICC and DMI tables
// Base address of descriptor upper map // Base address of descriptor upper map

View File

@ -148,7 +148,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
{ {
FLASH_DESCRIPTOR_MAP* descriptorMap; FLASH_DESCRIPTOR_MAP* descriptorMap;
FLASH_DESCRIPTOR_REGION_SECTION* regionSection; FLASH_DESCRIPTOR_REGION_SECTION* regionSection;
//FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection; FLASH_DESCRIPTOR_MASTER_SECTION* masterSection;
// Store the beginning of descriptor as descriptor base address // Store the beginning of descriptor as descriptor base address
UINT8* descriptor = (UINT8*) intelImage.constData(); UINT8* descriptor = (UINT8*) intelImage.constData();
@ -162,9 +162,9 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
} }
// Parse descriptor map // Parse descriptor map
descriptorMap = (FLASH_DESCRIPTOR_MAP*) (descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); descriptorMap = (FLASH_DESCRIPTOR_MAP*) (descriptor + sizeof(FLASH_DESCRIPTOR_HEADER));
regionSection = (FLASH_DESCRIPTOR_REGION_SECTION*) calculateAddress8(descriptor, descriptorMap->RegionBase); regionSection = (FLASH_DESCRIPTOR_REGION_SECTION*) calculateAddress8(descriptor, descriptorMap->RegionBase);
//componentSection = (FLASH_DESCRIPTOR_COMPONENT_SECTION*) calculateAddress8(descriptor, descriptorMap->ComponentBase); masterSection = (FLASH_DESCRIPTOR_MASTER_SECTION*) calculateAddress8(descriptor, descriptorMap->MasterBase);
// GbE region // GbE region
QByteArray gbe; QByteArray gbe;
@ -282,11 +282,11 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
QVector<UINT32> offsets; QVector<UINT32> offsets;
if (regionSection->GbeLimit) { if (regionSection->GbeLimit) {
offsets.append(gbeBegin); 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) { if (regionSection->MeLimit) {
offsets.append(meBegin); 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) { if (regionSection->BiosLimit) {
offsets.append(biosBegin); offsets.append(biosBegin);
@ -294,9 +294,38 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
} }
if (regionSection->PdrLimit) { if (regionSection->PdrLimit) {
offsets.append(pdrBegin); 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 // Add descriptor tree item
model->addItem(Region, DescriptorRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), body, QByteArray(), index); 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(); reconstructed.clear();
return ERR_SUCCESS; return ERR_SUCCESS;
} }
else if (model->action(index) == Insert || else if (model->action(index) == Insert ||
model->action(index) == Replace || model->action(index) == Replace ||
model->action(index) == Rebuild) { model->action(index) == Rebuild) {
QByteArray header = model->header(index); 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 // Check erase polarity
if (erasePolarity == ERASE_POLARITY_UNKNOWN) { 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 // File contains raw data, must be parsed as region
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) { if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW) {
result = reconstructRegion(index, reconstructed); result = reconstructRegion(index, reconstructed);
if (result) if (result)
return result; return result;
} }
// File contains sections // File contains sections
else { else {
UINT32 offset = 0; UINT32 offset = 0;
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
// Align to 4 byte boundary // Align to 4 byte boundary
UINT8 alignment = offset % 4; UINT8 alignment = offset % 4;
@ -2292,7 +2321,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
} }
// Calculate section base // 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 // Reconstruct section
QByteArray section; QByteArray section;
@ -2320,7 +2349,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
// Recalculate header checksum // Recalculate header checksum
fileHeader->IntegrityCheck.Checksum.Header = 0; fileHeader->IntegrityCheck.Checksum.Header = 0;
fileHeader->IntegrityCheck.Checksum.File = 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 // Use current file body
@ -2329,7 +2358,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
// 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*) reconstructed.constData(), reconstructed.size()); fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*)reconstructed.constData(), reconstructed.size());
} }
else if (revision == 1) else if (revision == 1)
fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM; 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; fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2;
// Append tail, if needed // Append tail, if needed
if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) if (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
reconstructed.append(~fileHeader->IntegrityCheck.TailReference); UINT8 ht = ~fileHeader->IntegrityCheck.Checksum.Header;
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
reconstructed.append(ht).append(ft);
}
// Set file state // Set file state
state = EFI_FILE_DATA_VALID | EFI_FILE_HEADER_VALID | EFI_FILE_HEADER_CONSTRUCTION; state = EFI_FILE_DATA_VALID | EFI_FILE_HEADER_VALID | EFI_FILE_HEADER_CONSTRUCTION;
if (erasePolarity == ERASE_POLARITY_TRUE) if (erasePolarity == ERASE_POLARITY_TRUE)

View File

@ -213,7 +213,7 @@ void UEFITool::insert(const UINT8 mode)
inputFile.setFileName(path); inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly)) { 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; return;
} }
@ -222,7 +222,7 @@ void UEFITool::insert(const UINT8 mode)
UINT8 result = ffsEngine->insert(index, buffer, mode); UINT8 result = ffsEngine->insert(index, buffer, mode);
if (result) 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 else
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
} }
@ -305,7 +305,7 @@ void UEFITool::replace(const UINT8 mode)
inputFile.setFileName(path); inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly)) { 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; return;
} }
@ -314,7 +314,7 @@ void UEFITool::replace(const UINT8 mode)
UINT8 result = ffsEngine->replace(index, buffer, mode); UINT8 result = ffsEngine->replace(index, buffer, mode);
if (result) 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 else
ui->actionSaveImageFile->setEnabled(true); ui->actionSaveImageFile->setEnabled(true);
} }
@ -380,7 +380,7 @@ void UEFITool::extract(const UINT8 mode)
break; break;
case Section: { case Section: {
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE) 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) 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 (*.*)"); 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) else if (model->subtype(index) == EFI_SECTION_RAW)
@ -396,22 +396,23 @@ void UEFITool::extract(const UINT8 mode)
else else
path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)"); path = QFileDialog::getSaveFileName(this, tr("Save object to file"),".","Binary files (*.bin);;All files (*.*)");
QFile outputFile; QByteArray extracted;
outputFile.setFileName(path); UINT8 result = ffsEngine->extract(index, extracted, mode);
if (!outputFile.open(QFile::WriteOnly)) { if (result) {
ui->statusBar->showMessage(tr("Can't open file for rewriting")); QMessageBox::critical(this, tr("Extraction failed"), tr("Error code: %d").arg(result), QMessageBox::Ok);
return; return;
} }
QByteArray extracted; QFile outputFile;
UINT8 result = ffsEngine->extract(index, extracted, mode); outputFile.setFileName(path);
if (result) if (!outputFile.open(QFile::WriteOnly)) {
ui->statusBar->showMessage(tr("File can't be extracted (%1)").arg(result)); QMessageBox::critical(this, tr("Extraction failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok);
else { return;
outputFile.resize(0);
outputFile.write(extracted);
outputFile.close();
} }
outputFile.resize(0);
outputFile.write(extracted);
outputFile.close();
} }
void UEFITool::about() 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 (*.*)"); 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; QByteArray reconstructed;
UINT8 result = ffsEngine->reconstructImageFile(reconstructed); UINT8 result = ffsEngine->reconstructImageFile(reconstructed);
showMessages(); showMessages();
if (result) { 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; return;
} }
outputFile.resize(0); outputFile.resize(0);
outputFile.write(reconstructed); outputFile.write(reconstructed);
outputFile.close(); 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() void UEFITool::openImageFile()
@ -479,7 +484,7 @@ void UEFITool::openImageFile(QString path)
inputFile.setFileName(path); inputFile.setFileName(path);
if (!inputFile.open(QFile::ReadOnly)) { 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; return;
} }
@ -490,7 +495,7 @@ void UEFITool::openImageFile(QString path)
UINT8 result = ffsEngine->parseImageFile(buffer); UINT8 result = ffsEngine->parseImageFile(buffer);
showMessages(); showMessages();
if (result) 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 else
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName())); ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));

View File

@ -20,7 +20,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>UEFITool 0.16.5</string> <string>UEFITool 0.16.6</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>
@ -64,6 +82,12 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="font">
<font>
<family>Consolas</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="indentation"> <property name="indentation">
<number>10</number> <number>10</number>
</property> </property>
@ -91,11 +115,26 @@
<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>
<widget class="QPlainTextEdit" name="infoEdit"> <widget class="QPlainTextEdit" name="infoEdit">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="acceptDrops"> <property name="acceptDrops">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -121,11 +160,27 @@
<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>
<widget class="QListWidget" name="messageListWidget"/> <widget class="QListWidget" name="messageListWidget">
<property name="font">
<font>
<family>Consolas</family>
<pointsize>9</pointsize>
</font>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>