NE Alpha 40

This commit is contained in:
Cr4sh 2017-02-14 09:39:16 +03:00
parent 7b18f346dd
commit 0f0bc32a42
25 changed files with 2012 additions and 137 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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 \

View file

@ -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

View file

@ -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 \

View file

@ -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;

View file

@ -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)

View file

@ -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();

View file

@ -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)
@ -1090,3 +1098,13 @@ void UEFITool::currentTabChanged(int index)
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);
}
}

View file

@ -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;

View file

@ -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

5
UEFITool/uefitool.qrc Normal file
View file

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="guids.csv">../common/guids.csv</file>
</qresource>
</RCC>

View file

@ -284,6 +284,8 @@
<addaction name="actionOpenImageFileInNewWindow"/>
<addaction name="actionSaveImageFile"/>
<addaction name="separator"/>
<addaction name="actionLoadGuidDatabase"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuHelp">
@ -789,6 +791,14 @@
<string>Ctrl+Shift+D</string>
</property>
</action>
<action name="actionLoadGuidDatabase">
<property name="text">
<string>Load &amp;GUID database...</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+G</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>

View file

@ -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

View file

@ -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");

View file

@ -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,

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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);

80
common/guiddatabase.cpp Normal file
View file

@ -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 <map>
#include <QFile>
#include <QUuid>
struct OperatorLessForGuids : public std::binary_function<EFI_GUID, EFI_GUID, bool>
{
bool operator()(const EFI_GUID& lhs, const EFI_GUID& rhs) const
{
return (memcmp(&lhs, &rhs, sizeof(EFI_GUID)) < 0);
}
};
typedef std::map<EFI_GUID, UString, OperatorLessForGuids> GuidToUStringMap;
static GuidToUStringMap gGuidToUStringMap;
void initGuidDatabase(const UString & path, UINT32* numEntries)
{
gGuidToUStringMap.clear();
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
UByteArray line = file.readLine();
// Use sharp sign as commentary
if (line.length() == 0 || line[0] == '#')
continue;
// GUID and name are comma-separated
QList<UByteArray> lineParts = line.split(',');
if (lineParts.length() < 2)
continue;
QUuid uuid(lineParts[0]);
UString str(lineParts[1].constData());
gGuidToUStringMap.insert(GuidToUStringMap::value_type(*(const EFI_GUID*)&uuid.data1, str.simplified()));
}
if (numEntries)
*numEntries = gGuidToUStringMap.size();
}
UString guidDatabaseLookup(const EFI_GUID & guid)
{
return gGuidToUStringMap[guid];
}
#else
void initGuidDatabase(const UString & path, UINT32* numEntries)
{
U_UNUSED_PARAMETER(path);
if (numEntries)
*numEntries = 0;
}
UString guidDatabaseLookup(const EFI_GUID & guid)
{
U_UNUSED_PARAMETER(guid);
return UString();
}
#endif

22
common/guiddatabase.h Normal file
View file

@ -0,0 +1,22 @@
/* guiddatabase.h
Copyright (c) 2017, Nikolaj Schlej. 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.
*/
#ifndef GUID_DATABASE_H
#define GUID_DATABASE_H
#include "basetypes.h"
#include "ustring.h"
UString guidDatabaseLookup(const EFI_GUID & guid);
void initGuidDatabase(const UString & path = "", UINT32* numEntries = NULL);
#endif // GUID_DATABASE_H

1713
common/guids.csv Normal file

File diff suppressed because it is too large Load diff

View file

@ -73,6 +73,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
UINT8 subtype = Subtypes::FullNvarEntry;
UString name;
UString guid;
UString text;
UByteArray header;
UByteArray body;
@ -267,6 +268,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// Get entry GUID
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) { // GUID is strored in the variable itself
name = guidToUString(*(EFI_GUID*)(entryHeader + 1));
guid = guidToUString(*(EFI_GUID*)(entryHeader + 1), false);
}
// GUID is stored in GUID list at the end of the store
else {
@ -277,6 +279,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// The list begins at the end of the store and goes backwards
const EFI_GUID* guidPtr = (const EFI_GUID*)(data.constData() + data.size()) - 1 - guidIndex;
name = guidToUString(*guidPtr);
guid = guidToUString(*guidPtr, false);
hasGuidIndex = true;
}
@ -300,7 +303,7 @@ parsing_done:
pdata.isValid = FALSE;
}
else // Add GUID info for valid entries
info += UString("Variable GUID: ") + name + UString("\n");
info += UString("Variable GUID: ") + guid + UString("\n");
// Add GUID index information
if (hasGuidIndex)
@ -817,7 +820,7 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
// Add info
UString name("FTW store");
UString info = UString("Signature: ") + guidToUString(ftw32BlockHeader->Signature) +
UString info = UString("Signature: ") + guidToUString(ftw32BlockHeader->Signature, false) +
usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh",
ftwBlockSize, ftwBlockSize,
headerSize, headerSize,
@ -1408,7 +1411,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index)
}
else { // Add GUID and text for valid variables
name = guidToUString(*variableGuid);
info += UString("Variable GUID: ") + name + UString("\n");
info += UString("Variable GUID: ") + guidToUString(*variableGuid, false) + UString("\n");
text = UString::fromUtf16(variableName);
}
@ -1613,7 +1616,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY));
EFI_GUID guid = *(EFI_GUID*)body.constData();
name = guidToUString(guid);
info = UString("GUID: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
info = UString("GUID: ") + guidToUString(guid, false) + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1631,7 +1634,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
header = data.mid(offset, sizeof(EVSA_NAME_ENTRY));
body = data.mid(offset + sizeof(EVSA_NAME_ENTRY), nameHeader->Header.Size - sizeof(EVSA_NAME_ENTRY));
name = UString::fromUtf16((const CHAR16*)body.constData());
info = UString("GUID: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
info = UString("Name: ") + name + usprintf("\nFull size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
variableSize, variableSize,
header.size(), header.size(),
body.size(), body.size(),
@ -1709,7 +1712,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)header.constData();
UString guid;
if (guidMap.count(dataHeader->GuidId))
guid = guidToUString(guidMap[dataHeader->GuidId]);
guid = guidToUString(guidMap[dataHeader->GuidId], false);
UString name;
if (nameMap.count(dataHeader->VarId))
name = nameMap[dataHeader->VarId];
@ -1788,7 +1791,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
UByteArray header = data.mid(offset, sizeof(PHOENIX_FLASH_MAP_ENTRY));
// Add info
UString info = UString("Entry GUID: ") + name + usprintf("\nFull size: 24h (36)\nHeader size: 24h (36)\nBody size: 0h (0)\n"
UString info = UString("Entry GUID: ") + guidToUString(entryHeader->Guid, false) + usprintf("\nFull size: 24h (36)\nHeader size: 24h (36)\nBody size: 0h (0)\n"
"Entry type: %04Xh\nData type: %04Xh\nMemory address: %08Xh\nSize: %08Xh\nOffset: %08Xh",
entryHeader->EntryType,
entryHeader->DataType,

View file

@ -36,20 +36,6 @@ UString uniqueItemName(const UModelIndex & index)
// Default name
UString name = itemName;
switch (model->type(index)) {
case Types::Volume: {
UINT8 hasExtendedHeader = FALSE;
EFI_GUID extendedHeaderGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
if (model->hasEmptyParsingData(index) == false) {
UByteArray data = model->parsingData(index);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
hasExtendedHeader = pdata->hasExtendedHeader;
extendedHeaderGuid = pdata->extendedHeaderGuid;
}
if (hasExtendedHeader)
name = guidToUString(extendedHeaderGuid);
name.findreplace('-', '_');
} break;
case Types::NvarEntry:
case Types::VssEntry:
case Types::FsysEntry: