diff --git a/UEFIDump/CMakeLists.txt b/UEFIDump/CMakeLists.txt
index e15ab1d..ef7ae4a 100644
--- a/UEFIDump/CMakeLists.txt
+++ b/UEFIDump/CMakeLists.txt
@@ -3,6 +3,7 @@ PROJECT(UEFIDump)
SET(PROJECT_SOURCES
uefidump_main.cpp
uefidump.cpp
+ ../common/guiddatabase.cpp
../common/types.cpp
../common/descriptor.cpp
../common/ffs.cpp
@@ -24,6 +25,7 @@ SET(PROJECT_SOURCES
SET(PROJECT_HEADERS
uefidump.h
+ ../common/guiddatabase.h
../common/basetypes.h
../common/descriptor.h
../common/gbe.h
diff --git a/UEFIDump/uefidump_main.cpp b/UEFIDump/uefidump_main.cpp
index 0445bb2..fb1a433 100644
--- a/UEFIDump/uefidump_main.cpp
+++ b/UEFIDump/uefidump_main.cpp
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS);
}
- std::cout << "UEFIDump 0.1.4" << std::endl << std::endl
+ std::cout << "UEFIDump 0.1.5" << std::endl << std::endl
<< "Usage: UEFIDump imagefile" << std::endl;
return 0;
}
diff --git a/UEFIExtract/uefiextract.pro b/UEFIExtract/uefiextract.pro
index b66f38e..68ffbab 100644
--- a/UEFIExtract/uefiextract.pro
+++ b/UEFIExtract/uefiextract.pro
@@ -10,6 +10,7 @@ DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT"
SOURCES += \
uefiextract_main.cpp \
ffsdumper.cpp \
+ ../common/guiddatabase.cpp \
../common/types.cpp \
../common/descriptor.cpp \
../common/ffs.cpp \
@@ -28,6 +29,7 @@ SOURCES += \
HEADERS += \
ffsdumper.h \
+ ../common/guiddatabase.h \
../common/basetypes.h \
../common/descriptor.h \
../common/gbe.h \
diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp
index 3c37fd2..ff3897c 100644
--- a/UEFIExtract/uefiextract_main.cpp
+++ b/UEFIExtract/uefiextract_main.cpp
@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
}
}
// If parameters are different, show version and usage information
- std::cout << "UEFIExtract 0.13.3" << std::endl << std::endl
+ std::cout << "UEFIExtract 0.13.4" << std::endl << std::endl
<< "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder." << std::endl
<< " UEFIExtract imagefile all - generate report and dump all tree items." << std::endl
<< " UEFIExtract imagefile dump - only generate dump, no report needed." << std::endl
diff --git a/UEFIFind/uefifind.pro b/UEFIFind/uefifind.pro
index 30b7374..19cd519 100644
--- a/UEFIFind/uefifind.pro
+++ b/UEFIFind/uefifind.pro
@@ -8,6 +8,7 @@ CONFIG -= app_bundle
SOURCES += uefifind_main.cpp \
uefifind.cpp \
+ ../common/guiddatabase.cpp \
../common/types.cpp \
../common/descriptor.cpp \
../common/ffs.cpp \
@@ -23,6 +24,7 @@ SOURCES += uefifind_main.cpp \
../common/ustring.cpp
HEADERS += uefifind.h \
+ ../common/guiddatabase.h \
../common/basetypes.h \
../common/descriptor.h \
../common/gbe.h \
diff --git a/UEFIFind/uefifind_main.cpp b/UEFIFind/uefifind_main.cpp
index d14f679..c55e0b2 100644
--- a/UEFIFind/uefifind_main.cpp
+++ b/UEFIFind/uefifind_main.cpp
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
return U_SUCCESS;
}
else {
- std::cout << "UEFIFind 0.10.7" << std::endl << std::endl <<
+ std::cout << "UEFIFind 0.10.8" << std::endl << std::endl <<
"Usage: UEFIFind {header | body | all} {list | count} pattern imagefile" << std::endl <<
" or UEFIFind file patternsfile imagefile" << std::endl;
return U_INVALID_PARAMETER;
diff --git a/UEFITool/qhexedit2/commands.cpp b/UEFITool/qhexedit2/commands.cpp
index e9530d5..ce9aee2 100644
--- a/UEFITool/qhexedit2/commands.cpp
+++ b/UEFITool/qhexedit2/commands.cpp
@@ -32,6 +32,8 @@ CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar
_charPos = charPos;
_newChar = newChar;
_cmd = cmd;
+ _wasChanged = false;
+ _oldChar = ' ';
}
bool CharCommand::mergeWith(const QUndoCommand *command)
diff --git a/UEFITool/qhexedit2/qhexedit.cpp b/UEFITool/qhexedit2/qhexedit.cpp
index e81189b..25e3151 100644
--- a/UEFITool/qhexedit2/qhexedit.cpp
+++ b/UEFITool/qhexedit2/qhexedit.cpp
@@ -846,7 +846,7 @@ void QHexEdit::paintEvent(QPaintEvent *event)
QByteArray hex;
int pxPosX = _pxPosHexX - pxOfsX;
int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX;
- qint64 bPosLine = row * _bytesPerLine;
+ qint64 bPosLine = (qint64)row * _bytesPerLine;
for (int colIdx = 0; ((bPosLine + colIdx) < _dataShown.size() && (colIdx < _bytesPerLine)); colIdx++)
{
QColor c = viewport()->palette().color(QPalette::Base);
@@ -1024,7 +1024,7 @@ void QHexEdit::adjust()
int value = verticalScrollBar()->value();
_bPosFirst = (qint64)value * _bytesPerLine;
- _bPosLast = _bPosFirst + (qint64)(_rowsShown * _bytesPerLine) - 1;
+ _bPosLast = _bPosFirst + ((qint64)_rowsShown * _bytesPerLine) - 1;
if (_bPosLast >= _chunks->size())
_bPosLast = _chunks->size() - 1;
readBuffers();
diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp
index 199e596..be05cd9 100644
--- a/UEFITool/uefitool.cpp
+++ b/UEFITool/uefitool.cpp
@@ -14,11 +14,10 @@
#include "uefitool.h"
#include "ui_uefitool.h"
-
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
-version(tr("NE Alpha 38"))
+version(tr("NE alpha 40"))
{
clipboard = QApplication::clipboard();
@@ -58,6 +57,8 @@ version(tr("NE Alpha 38"))
connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(exit()));
connect(ui->actionGoToData, SIGNAL(triggered()), this, SLOT(goToData()));
connect(ui->actionGoToOffset, SIGNAL(triggered()), this, SLOT(goToOffset()));
+ connect(ui->actionLoadGuidDatabase, SIGNAL(triggered()), this, SLOT(loadGuidDatabase()));
+ connect(ui->actionGoToOffset, SIGNAL(triggered()), this, SLOT(goToOffset()));
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings()));
// Enable Drag-and-Drop actions
@@ -84,6 +85,9 @@ version(tr("NE Alpha 38"))
hexViewDialog->setFont(font);
goToOffsetDialog->ui->hexSpinBox->setFont(font);
+ // Load built-in GUID database
+ initGuidDatabase(":/guids.csv");
+
// Initialize non-persistent data
init();
@@ -795,6 +799,7 @@ void UEFITool::openImageFile(QString path)
init();
setWindowTitle(tr("UEFITool %1 - %2").arg(version).arg(fileInfo.fileName()));
+ // Parse the image
UINT8 result = ffsParser->parse(buffer);
showParserMessages();
if (result) {
@@ -804,6 +809,9 @@ void UEFITool::openImageFile(QString path)
else
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
+ // Enable or disable FIT tab
+ showFitTable();
+
// Enable search ...
delete ffsFinder;
ffsFinder = new FfsFinder(model);
@@ -815,11 +823,11 @@ void UEFITool::openImageFile(QString path)
// Enable goToOffset
ui->actionGoToOffset->setEnabled(true);
- // Enable or disable FIT tab
- showFitTable();
-
// Set current directory
currentDir = fileInfo.absolutePath();
+
+ // Set current path
+ currentPath = path;
}
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
@@ -1089,4 +1097,14 @@ void UEFITool::currentTabChanged(int index)
ui->actionMessagesCopy->setEnabled(false);
ui->actionMessagesCopyAll->setEnabled(false);
ui->actionMessagesClear->setEnabled(false);
+}
+
+void UEFITool::loadGuidDatabase()
+{
+ QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, "GUID database files (*.gdb);;All files (*)");
+ if (!path.isEmpty()) {
+ initGuidDatabase(path);
+ if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("New GUID database loaded"), tr("Apply new GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No))
+ openImageFile(currentPath);
+ }
}
\ No newline at end of file
diff --git a/UEFITool/uefitool.h b/UEFITool/uefitool.h
index ddcb77f..e82098d 100644
--- a/UEFITool/uefitool.h
+++ b/UEFITool/uefitool.h
@@ -41,6 +41,7 @@
#include "../common/ffsparser.h"
#include "../common/ffsops.h"
#include "../common/ffsbuilder.h"
+#include "../common/guiddatabase.h"
#include "searchdialog.h"
#include "gotooffsetdialog.h"
@@ -110,6 +111,8 @@ private slots:
void exit();
void writeSettings();
+ void loadGuidDatabase();
+
void currentTabChanged(int index);
private:
@@ -124,6 +127,7 @@ private:
GoToOffsetDialog* goToOffsetDialog;
QClipboard* clipboard;
QString currentDir;
+ QString currentPath;
QString currentProgramPath;
const QString version;
diff --git a/UEFITool/uefitool.pro b/UEFITool/uefitool.pro
index 721d35c..7d01533 100644
--- a/UEFITool/uefitool.pro
+++ b/UEFITool/uefitool.pro
@@ -4,6 +4,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = UEFITool
TEMPLATE = app
DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT"
+DEFINES += "U_ENABLE_GUID_DATABASE_SUPPORT"
HEADERS += uefitool.h \
searchdialog.h \
@@ -12,6 +13,7 @@ HEADERS += uefitool.h \
guidlineedit.h \
ffsfinder.h \
hexspinbox.h \
+ ../common/guiddatabase.h \
../common/nvram.h \
../common/nvramparser.h \
../common/meparser.h \
@@ -47,6 +49,7 @@ SOURCES += uefitool_main.cpp \
guidlineedit.cpp \
ffsfinder.cpp \
hexspinbox.cpp \
+ ../common/guiddatabase.cpp \
../common/nvram.cpp \
../common/nvramparser.cpp \
../common/ffsops.cpp \
@@ -77,7 +80,7 @@ FORMS += uefitool.ui \
hexviewdialog.ui \
gotooffsetdialog.ui
+RESOURCES += uefitool.qrc
RC_FILE = uefitool.rc
-
ICON = icons/uefitool.icns
diff --git a/UEFITool/uefitool.qrc b/UEFITool/uefitool.qrc
new file mode 100644
index 0000000..9b463ae
--- /dev/null
+++ b/UEFITool/uefitool.qrc
@@ -0,0 +1,5 @@
+
+
+ ../common/guids.csv
+
+
\ No newline at end of file
diff --git a/UEFITool/uefitool.ui b/UEFITool/uefitool.ui
index 732f1dc..c8dbbe2 100644
--- a/UEFITool/uefitool.ui
+++ b/UEFITool/uefitool.ui
@@ -284,6 +284,8 @@
+
+
diff --git a/common/basetypes.h b/common/basetypes.h
index 201171a..3071ce7 100644
--- a/common/basetypes.h
+++ b/common/basetypes.h
@@ -57,6 +57,8 @@ typedef uint8_t USTATUS;
#define U_TRUNCATED_IMAGE 36
#define U_INVALID_CAPSULE 37
#define U_STORES_NOT_FOUND 38
+#define U_INVALID_IMAGE 39
+#define U_INVALID_RAW_AREA 40
#define U_NOT_IMPLEMENTED 0xFF
// UDK porting definitions
diff --git a/common/descriptor.cpp b/common/descriptor.cpp
index c289f76..2365b2c 100644
--- a/common/descriptor.cpp
+++ b/common/descriptor.cpp
@@ -57,10 +57,10 @@ UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1)
case 0xEF4017: return UString("Winbond W25Q64");
case 0xEF4018: return UString("Winbond W25Q128");
case 0xEF4019: return UString("Winbond W25Q256");
- case 0xEF6015: return UString("Winbond W25Q16 1.8v");
- case 0xEF6016: return UString("Winbond W25Q32 1.8v");
- case 0xEF6017: return UString("Winbond W25Q64 1.8v");
- case 0xEF6018: return UString("Winbond W25Q128 1.8v");
+ case 0xEF6015: return UString("Winbond W25Q16");
+ case 0xEF6016: return UString("Winbond W25Q32");
+ case 0xEF6017: return UString("Winbond W25Q64");
+ case 0xEF6018: return UString("Winbond W25Q128");
// Macronix
case 0xC22013: return UString("Macronix MX25L40");
@@ -107,12 +107,12 @@ UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1)
case 0x20BA19: return UString("Micron N25Q256");
case 0x20BA20: return UString("Micron N25Q512");
case 0x20BA21: return UString("Micron N25Q00A");
- case 0x20BB15: return UString("Micron N25Q016 1.8v");
- case 0x20BB16: return UString("Micron N25Q032 1.8v");
- case 0x20BB17: return UString("Micron N25Q064 1.8v");
- case 0x20BB18: return UString("Micron MT25Q128 1.8v");
- case 0x20BB19: return UString("Micron MT25Q256 1.8v");
- case 0x20BB20: return UString("Micron MT25Q512 1.8v");
+ case 0x20BB15: return UString("Micron N25Q016");
+ case 0x20BB16: return UString("Micron N25Q032");
+ case 0x20BB17: return UString("Micron N25Q064");
+ case 0x20BB18: return UString("Micron MT25Q128");
+ case 0x20BB19: return UString("Micron MT25Q256");
+ case 0x20BB20: return UString("Micron MT25Q512");
// Atmel
case 0x1F4500: return UString("Atmel AT26DF081");
diff --git a/common/ffs.cpp b/common/ffs.cpp
index a6d25d8..97e119f 100644
--- a/common/ffs.cpp
+++ b/common/ffs.cpp
@@ -11,6 +11,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "ffs.h"
+#include "guiddatabase.h"
// This is a workaround for the lack of static std::vector initializer before C++11
const UByteArray FFSv2VolumesInt[] = {
@@ -43,8 +44,14 @@ UINT32 uint24ToUint32(const UINT8* ffsSize)
return *(UINT32*)ffsSize & 0x00FFFFFF;
}
-UString guidToUString(const EFI_GUID & guid)
+UString guidToUString(const EFI_GUID & guid, bool convertToString)
{
+ if (convertToString) {
+ UString readableName = guidDatabaseLookup(guid);
+ if (!readableName.isEmpty())
+ return readableName;
+ }
+
return usprintf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
guid.Data1,
guid.Data2,
diff --git a/common/ffs.h b/common/ffs.h
index 99799f5..5a18e2e 100644
--- a/common/ffs.h
+++ b/common/ffs.h
@@ -22,7 +22,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Make sure we use right packing rules
#pragma pack(push,1)
-extern UString guidToUString(const EFI_GUID& guid);
+extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
extern UString fileTypeToUString(const UINT8 type);
extern UString sectionTypeToUString(const UINT8 type);
diff --git a/common/ffsbuilder.cpp b/common/ffsbuilder.cpp
index d31e512..d943ef8 100644
--- a/common/ffsbuilder.cpp
+++ b/common/ffsbuilder.cpp
@@ -19,13 +19,26 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
{
- U_UNUSED_PARAMETER(erased);
-
// Sanity check
if (!index.isValid())
return U_INVALID_PARAMETER;
- return U_NOT_IMPLEMENTED;
+ // Try to get emptyByte value from item's parsing data
+ UINT8 emptyByte = 0xFF;
+ if (!model->hasEmptyParsingData(index)) {
+ if (model->type(index) == Types::Volume) {
+ VOLUME_PARSING_DATA pdata = *(VOLUME_PARSING_DATA*)model->parsingData(index).constData();
+ emptyByte = pdata.emptyByte;
+ }
+ else if (model->type(index) == Types::File) {
+ FILE_PARSING_DATA pdata = *(FILE_PARSING_DATA*)model->parsingData(index).constData();
+ emptyByte = pdata.emptyByte;
+ }
+ }
+
+ erased = QByteArray(model->header(index).size() + model->body(index).size() + model->tail(index).size(), emptyByte);
+
+ return U_SUCCESS;
}
USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image)
@@ -55,10 +68,10 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
if (!index.isValid())
return U_INVALID_PARAMETER;
- // No action required
+ // No action
if (model->action(index) == Actions::NoAction) {
// Use original item data
- capsule = model->header(index).append(model->body(index));
+ capsule = model->header(index) + model->body(index) + model->tail(index);
return U_SUCCESS;
}
@@ -71,10 +84,8 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
// Right now there is only one capsule image element supported
if (model->rowCount(index) != 1) {
- //msg(UString("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
- // Use original item data
- capsule = model->header(index).append(model->body(index));
- return U_SUCCESS;
+ msg(usprintf("buildCapsule: building of capsules with %d items is not yet supported", model->rowCount(index)), index);
+ return U_NOT_IMPLEMENTED;
}
// Build image
@@ -91,46 +102,44 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
result = buildRawArea(imageIndex, imageData);
}
else {
- //msg(UString("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
- capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
+ msg(UString("buildCapsule: unexpected item subtype ") + itemSubtypeToUString(model->type(imageIndex), model->subtype(imageIndex)), imageIndex);
+ return U_UNKNOWN_ITEM_TYPE;
}
// Check build result
if (result) {
- //msg(UString("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToUString(result)), imageIndex);
- capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
+ msg(UString("buildCapsule: building of ") + model->name(imageIndex) + UString(" failed with error ") + errorCodeToUString(result), imageIndex);
+ return result;
}
else
capsule.append(imageData);
}
else {
- //msg(UString("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
- capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
+ msg(UString("buildCapsule: unexpected item type ") + itemTypeToUString(model->type(imageIndex)), imageIndex);
+ return U_UNKNOWN_ITEM_TYPE;
}
- // Check size of reconstructed capsule, it must remain the same
+ // Check size of reconstructed capsule body, it must remain the same
UINT32 newSize = capsule.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
- //msg(UString("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildCapsule: new capsule size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_CAPSULE;
}
else if (newSize < oldSize) {
- //msg(UString("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildCapsule: new capsule size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_CAPSULE;
}
}
else
capsule = model->body(index);
- // Build successful, append header
- capsule = model->header(index).append(capsule);
+ // Build successful, append header and tail
+ capsule = model->header(index) + capsule + model->tail(index);
return U_SUCCESS;
}
- //msg(UString("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
+ msg(UString("buildCapsule: unexpected action " + actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
@@ -142,16 +151,18 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
// No action
if (model->action(index) == Actions::NoAction) {
- intelImage = model->header(index).append(model->body(index));
+ intelImage = model->header(index) + model->body(index) + model->tail(index);
+ return U_SUCCESS;
+ }
+ // Remove
+ else if (model->action(index) == Actions::Remove) {
+ intelImage.clear();
return U_SUCCESS;
}
-
// Rebuild
else if (model->action(index) == Actions::Rebuild) {
- intelImage.clear();
-
- // First child will always be descriptor for this type of image, and it's read only
- intelImage.append(model->header(index.child(0, 0)).append(model->body(index.child(0, 0))));
+ // First child will always be descriptor for this type of image, and it's read only for now
+ intelImage = model->header(index.child(0, 0)) + model->body(index.child(0, 0)) + model->tail(index.child(0, 0));
// Process other regions
for (int i = 1; i < model->rowCount(index); i++) {
@@ -165,7 +176,7 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
UINT8 type = model->type(currentRegion);
if (type == Types::Padding) {
// Add padding as is
- intelImage.append(model->header(currentRegion).append(model->body(currentRegion)));
+ intelImage.append(model->header(currentRegion) + model->body(currentRegion) + model->tail(currentRegion));
continue;
}
@@ -178,8 +189,8 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
case Subtypes::PdrRegion:
result = buildRawArea(currentRegion, region);
if (result) {
- //msg(UString("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
- region = model->header(currentRegion).append(model->body(currentRegion));
+ msg(UString("buildIntelImage: building of region ") + regionTypeToUString(regionType) + UString(" failed with error ") + errorCodeToUString(result), currentRegion);
+ return result;
}
break;
case Subtypes::GbeRegion:
@@ -193,7 +204,7 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
region = model->header(currentRegion).append(model->body(currentRegion));
break;
default:
- msg(UString("buildIntelImage: don't know how to build region of unknown type"), index);
+ msg(UString("buildIntelImage: unknown region type"), currentRegion);
return U_UNKNOWN_ITEM_TYPE;
}
@@ -205,25 +216,24 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
UINT32 newSize = intelImage.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
- //msg(UString("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildIntelImage: new image size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_IMAGE;
}
else if (newSize < oldSize) {
- //msg(UString("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildIntelImage: new image size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_IMAGE;
}
- // Reconstruction successful
+ // Build successful, append header and tail
+ intelImage = model->header(index) + intelImage + model->tail(index);
return U_SUCCESS;
}
- //msg(UString("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
+ msg(UString("buildIntelImage: unexpected action " + actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
-USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader)
+USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea)
{
// Sanity check
if (!index.isValid())
@@ -231,13 +241,18 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
// No action required
if (model->action(index) == Actions::NoAction) {
- rawArea = model->header(index).append(model->body(index));
+ rawArea = model->header(index) + model->body(index) + model->tail(index);
+ return U_SUCCESS;
+ }
+ // Remove
+ else if (model->action(index) == Actions::Remove) {
+ rawArea.clear();
return U_SUCCESS;
}
-
// Rebuild or Replace
else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) {
+ // Rebuild if there is at least 1 child
if (model->rowCount(index)) {
// Clear the supplied UByteArray
rawArea.clear();
@@ -255,13 +270,13 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
result = buildPadding(currentChild, currentData);
}
else {
- //msg(UString("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
- currentData = model->header(currentChild).append(model->body(currentChild));
+ msg(UString("buildRawArea: unexpected item type ") + itemTypeToUString(model->type(currentChild)), currentChild);
+ return U_UNKNOWN_ITEM_TYPE;
}
// Check build result
if (result) {
- //msg(UString("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
- currentData = model->header(currentChild).append(model->body(currentChild));
+ msg(UString("buildRawArea: building of ") + model->name(currentChild) + UString(" failed with error ") + errorCodeToUString(result), currentChild);
+ return result;
}
// Append current data
rawArea.append(currentData);
@@ -271,26 +286,25 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
UINT32 newSize = rawArea.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
- //msg(UString("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildRawArea: new area size %Xh (%u) is bigger than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_RAW_AREA;
}
else if (newSize < oldSize) {
- //msg(UString("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
- // .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
- return U_INVALID_PARAMETER;
+ msg(usprintf("buildRawArea: new area size %Xh (%u) is smaller than the original %Xh (%u)", newSize, newSize, oldSize, oldSize), index);
+ return U_INVALID_RAW_AREA;
}
}
- else
+ // No need to rebuild a raw area with no children
+ else {
rawArea = model->body(index);
+ }
// Build successful, add header if needed
- if (addHeader)
- rawArea = model->header(index).append(rawArea);
+ rawArea = model->header(index) + rawArea + model->tail(index);
return U_SUCCESS;
}
- //msg(UString("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
+ msg(UString("buildRawArea: unexpected action " + actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
@@ -302,19 +316,20 @@ USTATUS FfsBuilder::buildPadding(const UModelIndex & index, UByteArray & padding
// No action required
if (model->action(index) == Actions::NoAction) {
- padding = model->header(index).append(model->body(index));
+ padding = model->header(index) + model->body(index) + model->tail(index);
+ return U_SUCCESS;
+ }
+ // Remove
+ else if (model->action(index) == Actions::Remove) {
+ padding.clear();
return U_SUCCESS;
}
-
// Erase
else if (model->action(index) == Actions::Erase) {
- padding = model->header(index).append(model->body(index));
- if(erase(index, padding))
- msg(UString("buildPadding: erase failed, original item data is used"), index);
- return U_SUCCESS;
+ return erase(index, padding);
}
- //msg(UString("buildPadding: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
+ msg(UString("buildPadding: unexpected action " + actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
@@ -326,19 +341,22 @@ USTATUS FfsBuilder::buildNonUefiData(const UModelIndex & index, UByteArray & dat
// No action required
if (model->action(index) == Actions::NoAction) {
- data = model->header(index).append(model->body(index));
+ data = model->header(index) + model->body(index) + model->tail(index);
+ return U_SUCCESS;
+ }
+ // Remove
+ else if (model->action(index) == Actions::Remove) {
+ data.clear();
return U_SUCCESS;
}
-
// Erase
else if (model->action(index) == Actions::Erase) {
- data = model->header(index).append(model->body(index));
- if (erase(index, data))
- msg(UString("buildNonUefiData: erase failed, original item data is used"), index);
- return U_SUCCESS;
+ return erase(index, data);
}
- //msg(UString("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
+ // TODO: rebuild properly
+
+ msg(UString("buildNoUefiData: unexpected action " + actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
@@ -348,14 +366,9 @@ USTATUS FfsBuilder::buildFreeSpace(const UModelIndex & index, UByteArray & freeS
if (!index.isValid())
return U_INVALID_PARAMETER;
- // No action required
- if (model->action(index) == Actions::NoAction) {
- freeSpace = model->header(index).append(model->body(index));
- return U_SUCCESS;
- }
-
- //msg(UString("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
- return U_NOT_IMPLEMENTED;
+ // No actions possible for free space
+ freeSpace = model->header(index) + model->body(index) + model->tail(index);
+ return U_SUCCESS;
}
USTATUS FfsBuilder::buildVolume(const UModelIndex & index, UByteArray & volume)
diff --git a/common/ffsbuilder.h b/common/ffsbuilder.h
index 70f126e..03dbc62 100644
--- a/common/ffsbuilder.h
+++ b/common/ffsbuilder.h
@@ -41,7 +41,7 @@ private:
USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
- USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader = true);
+ USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea);
USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp
index 1ba9264..1b2bdf6 100644
--- a/common/ffsparser.cpp
+++ b/common/ffsparser.cpp
@@ -41,6 +41,7 @@ struct REGION_INFO {
USTATUS FfsParser::parse(const UByteArray & buffer)
{
UModelIndex root;
+
USTATUS result = performFirstPass(buffer, root);
addOffsetsRecursive(root);
if (result)
@@ -92,7 +93,7 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
UByteArray header = buffer.left(capsuleHeaderSize);
UByteArray body = buffer.mid(capsuleHeaderSize);
UString name("UEFI capsule");
- UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid) +
+ UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
buffer.size(), buffer.size(),
capsuleHeaderSize, capsuleHeaderSize,
@@ -126,7 +127,7 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
UByteArray header = buffer.left(capsuleHeaderSize);
UByteArray body = buffer.mid(capsuleHeaderSize);
UString name("Toshiba capsule");
- UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid) +
+ UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
buffer.size(), buffer.size(),
capsuleHeaderSize, capsuleHeaderSize,
@@ -168,7 +169,7 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
UByteArray header = buffer.left(capsuleHeaderSize);
UByteArray body = buffer.mid(capsuleHeaderSize);
UString name("AMI Aptio capsule");
- UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid) +
+ UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh",
buffer.size(), buffer.size(),
capsuleHeaderSize, capsuleHeaderSize,
@@ -1029,7 +1030,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
volumeHeader->ZeroVector[4], volumeHeader->ZeroVector[5], volumeHeader->ZeroVector[6], volumeHeader->ZeroVector[7],
volumeHeader->ZeroVector[8], volumeHeader->ZeroVector[9], volumeHeader->ZeroVector[10], volumeHeader->ZeroVector[11],
volumeHeader->ZeroVector[12], volumeHeader->ZeroVector[13], volumeHeader->ZeroVector[14], volumeHeader->ZeroVector[15])
- + guidToUString(volumeHeader->FileSystemGuid) \
+ + guidToUString(volumeHeader->FileSystemGuid, false) \
+ usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRevision: %u\nAttributes: %08Xh\nErase polarity: %u\nChecksum: %04Xh",
volumeSize, volumeSize,
headerSize, headerSize,
@@ -1044,7 +1045,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
const EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (const EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset);
info += usprintf("\nExtended header size: %Xh (%u)\nVolume GUID: ",
- extendedHeader->ExtHeaderSize, extendedHeader->ExtHeaderSize) + guidToUString(extendedHeader->FvName);
+ extendedHeader->ExtHeaderSize, extendedHeader->ExtHeaderSize) + guidToUString(extendedHeader->FvName, false);
+ name = guidToUString(extendedHeader->FvName); // Replace FFS GUID with volume GUID
}
// Add text
@@ -1458,7 +1460,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
else
name = UString("Pad-file");
- info = UString("File GUID: ") + guidToUString(fileHeader->Name) +
+ info = UString("File GUID: ") + guidToUString(fileHeader->Name, false) +
usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh",
fileHeader->Type,
fileHeader->Attributes,
@@ -1493,7 +1495,6 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
pdata.guid = fileHeader->Name;
model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata)));
-
// Override lastVtf index, if needed
if (isVtf) {
lastVtf = index;
@@ -2014,7 +2015,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
// Get info
UString name = guidToUString(guid);
- UString info = UString("Section GUID: ") + name +
+ UString info = UString("Section GUID: ") + guidToUString(guid, false) +
usprintf("\nType: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nAttributes: %04Xh",
sectionHeader->Type,
section.size(), section.size(),
@@ -2113,7 +2114,7 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
section.size(), section.size(),
header.size(), header.size(),
body.size(), body.size())
- + guidToUString(guid);
+ + guidToUString(guid, false);
// Add tree item
if (insertIntoTree) {
@@ -2655,7 +2656,7 @@ USTATUS FfsParser::parseRawSectionBody(const UModelIndex & index)
return U_SUCCESS;
}
- else if (parentFileGuid == NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID) {
+ else if (parentFileGuid == NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID) { // AMI NVRAM external defaults
// Parse NVAR area
nvramParser.parseNvarStore(index);
diff --git a/common/guiddatabase.cpp b/common/guiddatabase.cpp
new file mode 100644
index 0000000..ddfe5be
--- /dev/null
+++ b/common/guiddatabase.cpp
@@ -0,0 +1,80 @@
+/* guiddatabase.cpp
+
+Copyright (c) 2017, LongSoft. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*/
+
+#include "guiddatabase.h"
+#include "ubytearray.h"
+
+// TODO: remove Qt dependency
+#if defined(U_ENABLE_GUID_DATABASE_SUPPORT) && defined(QT_CORE_LIB)
+#include