Compare commits

...

29 commits

Author SHA1 Message Date
vit9696
f4937c8f09 Make appveyor like artifacts 2018-05-08 21:36:20 +03:00
vit9696
02cca631d9 Fix appveyour deploy 2018-05-08 19:51:12 +03:00
vit9696
0d90cad807 Increment version 2018-05-08 19:35:14 +03:00
vit9696
a5667c2866 Watch out for invalid variables 2018-05-08 19:33:00 +03:00
vit9696
d130533e32 Sync tianocompress with upstream and more warning fixes 2018-05-08 19:02:25 +03:00
vit9696
02cce9c6bd Include offset in FfsReport 2018-05-08 18:44:49 +03:00
vit9696
2042d07d72 Silence analyzer warnings and fix potential issues 2018-05-08 18:42:16 +03:00
vit9696
e7ca5715d5 Fix and reindent LZMA 2018-05-08 18:16:28 +03:00
vit9696
8abd090b07 Slightly more portable PRIX64 workaround 2018-05-08 10:48:04 +03:00
vit9696
29c7d2cd91 Fix Linux compilation 2018-05-08 03:02:07 +03:00
vit9696
fc1e614d02 Initial Windows build support for NE 2018-05-08 02:48:34 +03:00
vit9696
4b2b997079 Watch out for qmake failures on Linux 2018-05-07 21:43:12 +03:00
vit9696
8864d99c82 Add Linux x86-64 CI support 2018-05-07 21:28:45 +03:00
vit9696
1bd7d38990 Fix a compiler warning 2018-05-07 20:55:25 +03:00
vit9696
c61c954401 Improve descriptor version handling 2018-05-07 00:38:06 +03:00
vit9696
8415fc8781 1.0 descriptors should go via FLASH_DESCRIPTOR_MASTER_SECTION_V2 2018-05-06 15:34:34 +03:00
vit9696
fc82bce195 Fix Intel descriptor version parsing 2018-05-06 15:22:25 +03:00
vit9696
0438dbbd46 Version bump 2018-05-04 21:52:25 +03:00
vit9696
d666ca1434 Backport TianoDecompress fix for Xcode (https://bugzilla.tianocore.org/show_bug.cgi?id=635) 2018-05-04 20:48:02 +03:00
vit9696
086bbbd410
Merge pull request #131 from vit9696/new_engine
Travis Mac NE
2018-05-04 06:51:51 +03:00
vit9696
4f068130da Add deloy key 2018-05-04 06:41:01 +03:00
vit9696
1b9444d2f7 Implement mac builds with deploy and fix Linux builds 2018-05-03 22:26:28 +03:00
Alex Matrosov
848072dfe8
Update ffsparser.cpp 2018-04-29 22:41:13 -07:00
Alex Matrosov
1dc5457757
Update uefitool.cpp 2018-04-29 22:35:51 -07:00
Alex Matrosov
bbd613a166 bugfix 2018-04-29 22:33:19 -07:00
Alex Matrosov
775ad7d25b bugfix 2018-02-25 15:33:54 -08:00
Cr4sh
9edda8a800 NE Alpha 46 2018-02-15 06:02:53 +03:00
Alex Matrosov
39700d3cde multiple fixes 2018-01-23 00:00:03 -08:00
Alex Matrosov
d380888c0c
Update ffsparser.cpp 2017-12-10 21:39:47 -08:00
39 changed files with 1521 additions and 1126 deletions

28
.appveyor.yml Normal file
View file

@ -0,0 +1,28 @@
image: Visual Studio 2015
environment:
matrix:
- MSYS2_ARCH: i686
MSYSTEM: MINGW32
clone_depth: 10
build_script:
- cd %APPVEYOR_BUILD_FOLDER%
- set PATH=C:\msys64\mingw32\bin;C:\msys64\usr\bin;%PATH%
- bash ./unixbuild.sh
deploy:
provider: GitHub
force_update: true
auth_token:
secure: zSJnpSnrKY1NO5RPVBaD/uq7UPyc+GW7ecjPFqEMsLjtnd6H+iNfROdoeuxJgt5T
artifact: Binaries
on:
appveyor_repo_tag: true
artifacts:
- path: dist\**\*.zip
name: Binaries

7
.gitignore vendored
View file

@ -231,3 +231,10 @@ pip-log.txt
############# #############
*.o *.o
Makefile Makefile
UEFITool/uefitool_plugin_import.cpp
UEFITool.app/
.qmake.stash
CMakeCache.txt
CMakeFiles
cmake_install.cmake

View file

@ -1,28 +1,52 @@
language: cpp language: cpp
compiler: gcc matrix:
sudo: require include:
dist: trusty - os: osx
osx_image: xcode9.2
before_install: compiler: clang
- sudo add-apt-repository ppa:beineri/opt-qt58-trusty -y
- sudo apt-get update -qq
install:
- sudo apt-get -y install qt58base
- source /opt/qt58/bin/qt58-env.sh
script: script:
- cd UEFITool - ./unixbuild.sh
- qmake PREFIX=/usr
- make -j4 deploy:
- mkdir -p appdir/usr/bin ; mkdir -p appdir/usr/share/{applications,icons} ; cd appdir provider: releases
- cp ../UEFITool usr/bin/uefitool skip_cleanup: true
- cp ../uefitool.desktop . file: "dist/*.zip"
- cp ../icons/uefitool_256x256.png uefitool.png file_glob: true
- cd .. api_key:
- wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/3/linuxdeployqt-3-x86_64.AppImage" secure: "WjYd93lVLKHULBpUXS/WtGrkdXyAwxHOUnLJotyDmQipAQP5Ox7Kj12JwkSJGEmVOEdcbIQJyi0QxPjn1UYbYsAt6Op8zrjnYLS4G4fMdBtcxprWzid85uTW7oAAIFs7ygMVhpzxRKpu70yNb683vbThqNmaOu6RyG9aJOLtPAg="
- chmod a+x linuxdeployqt*.AppImage on:
- unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH tags: true
- ./linuxdeployqt*.AppImage ./appdir/usr/bin/* -bundle-non-qt-libs
- ./linuxdeployqt*.AppImage ./appdir/usr/bin/* -appimage - os: linux
- curl --upload-file ./UEFITool-*.AppImage https://transfer.sh/UEFITool-git.$(git rev-parse --short HEAD)-x86_64.AppImage dist: trusty
compiler: clang
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq qt5-default qt5-qmake qtbase5-dev-tools cmake
script:
- ./unixbuild.sh
- os: linux
dist: trusty
compiler: gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq qt5-default qt5-qmake qtbase5-dev-tools cmake
script:
- ./unixbuild.sh
deploy:
provider: releases
skip_cleanup: true
file: "dist/*.zip"
file_glob: true
api_key:
secure: "WjYd93lVLKHULBpUXS/WtGrkdXyAwxHOUnLJotyDmQipAQP5Ox7Kj12JwkSJGEmVOEdcbIQJyi0QxPjn1UYbYsAt6Op8zrjnYLS4G4fMdBtcxprWzid85uTW7oAAIFs7ygMVhpzxRKpu70yNb683vbThqNmaOu6RyG9aJOLtPAg="
on:
tags: true

View file

@ -1,6 +1,6 @@
/* uefidump_main.cpp /* uefidump_main.cpp
Copyright (c) 2017, LongSoft. All rights reserved. Copyright (c) 2018, LongSoft. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -29,7 +29,7 @@ int main(int argc, char *argv[])
return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS); return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS);
} }
std::cout << "UEFIDump 0.1.6" << std::endl << std::endl std::cout << "UEFIDump 0.1.9" << std::endl << std::endl
<< "Usage: UEFIDump imagefile" << std::endl; << "Usage: UEFIDump imagefile" << std::endl;
return 0; return 0;
} }

View file

@ -25,7 +25,7 @@ SOURCES += \
../common/LZMA/LzmaDecompress.c \ ../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/LzmaDec.c \ ../common/LZMA/SDK/C/LzmaDec.c \
../common/Tiano/EfiTianoDecompress.c \ ../common/Tiano/EfiTianoDecompress.c \
../common/ustring.cpp ../common/ustring.cpp \
../common/sha256.c ../common/sha256.c
HEADERS += \ HEADERS += \

View file

@ -1,5 +1,5 @@
/* uefiextract_main.cpp /* uefiextract_main.cpp
Copyright (c) 2017, LongSoft. All rights reserved. Copyright (c) 2018, LongSoft. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -121,7 +121,7 @@ int main(int argc, char *argv[])
} }
} }
// If parameters are different, show version and usage information // If parameters are different, show version and usage information
std::cout << "UEFIExtract 0.13.5" << std::endl << std::endl std::cout << "UEFIExtract 0.13.8" << std::endl << std::endl
<< "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder." << 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 all - generate report and dump all tree items." << std::endl
<< " UEFIExtract imagefile dump - only generate dump, no report needed." << std::endl << " UEFIExtract imagefile dump - only generate dump, no report needed." << std::endl
@ -129,4 +129,4 @@ int main(int argc, char *argv[])
<< " UEFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s), without report." << std::endl << " UEFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s), without report." << std::endl
<< "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl; << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl;
return 1; return 1;
} }

View file

@ -1,6 +1,6 @@
/* uefifind_main.cpp /* uefifind_main.cpp
Copyright (c) 2017, LongSoft. All rights reserved. Copyright (c) 2018, LongSoft. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -148,7 +148,7 @@ int main(int argc, char *argv[])
return U_SUCCESS; return U_SUCCESS;
} }
else { else {
std::cout << "UEFIFind 0.10.10" << std::endl << std::endl << std::cout << "UEFIFind 0.10.13" << std::endl << std::endl <<
"Usage: UEFIFind {header | body | all} {list | count} pattern imagefile" << std::endl << "Usage: UEFIFind {header | body | all} {list | count} pattern imagefile" << std::endl <<
" or UEFIFind file patternsfile imagefile" << std::endl; " or UEFIFind file patternsfile imagefile" << std::endl;
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;

View file

@ -47,8 +47,8 @@ void HexViewDialog::setItem(const UModelIndex & index, bool bodyOnly)
setWindowTitle(UString("Hex view: ") + (itemText.isEmpty() ? itemName : itemName + " | " + itemText)); setWindowTitle(UString("Hex view: ") + (itemText.isEmpty() ? itemName : itemName + " | " + itemText));
// Set hex data // Set hex data
QByteArray data; QByteArray hexdata;
if (bodyOnly) data = model->body(index); if (bodyOnly) hexdata = model->body(index);
else data = model->header(index) + model->body(index) + model->tail(index); else hexdata = model->header(index) + model->body(index) + model->tail(index);
hexView->setData(data); hexView->setData(hexdata);
} }

View file

@ -165,7 +165,7 @@ void QHexEdit::setCursorPosition(qint64 position)
// 3. Calc new position of cursor // 3. Calc new position of cursor
_bPosCurrent = position / 2; _bPosCurrent = position / 2;
_pxCursorY = ((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight; _pxCursorY = (int)((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight;
int x = (position % (2 * _bytesPerLine)); int x = (position % (2 * _bytesPerLine));
if (_editAreaIsAscii) if (_editAreaIsAscii)
{ {
@ -341,7 +341,7 @@ void QHexEdit::insert(qint64 pos, const QByteArray &ba)
void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba) void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba)
{ {
_undoStack->overwrite(pos, len, ba); _undoStack->overwrite(pos, (int)len, ba);
refresh(); refresh();
} }

View file

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("NE alpha 45")) version(tr("NE alpha 50"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -32,6 +32,7 @@ version(tr("NE alpha 45"))
ffsFinder = NULL; ffsFinder = NULL;
ffsOps = NULL; ffsOps = NULL;
ffsBuilder = NULL; ffsBuilder = NULL;
ffsReport = NULL;
// Connect signals to slots // Connect signals to slots
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile())); connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
@ -60,35 +61,21 @@ version(tr("NE alpha 45"))
connect(ui->actionGoToOffset, SIGNAL(triggered()), this, SLOT(goToOffset())); connect(ui->actionGoToOffset, SIGNAL(triggered()), this, SLOT(goToOffset()));
connect(ui->actionGoToAddress, SIGNAL(triggered()), this, SLOT(goToAddress())); connect(ui->actionGoToAddress, SIGNAL(triggered()), this, SLOT(goToAddress()));
connect(ui->actionLoadGuidDatabase, SIGNAL(triggered()), this, SLOT(loadGuidDatabase())); connect(ui->actionLoadGuidDatabase, SIGNAL(triggered()), this, SLOT(loadGuidDatabase()));
connect(ui->actionUnloadGuidDatabase, SIGNAL(triggered()), this, SLOT(unloadGuidDatabase()));
connect(ui->actionLoadDefaultGuidDatabase, SIGNAL(triggered()), this, SLOT(loadDefaultGuidDatabase()));
connect(ui->actionGenerateReport, SIGNAL(triggered()), this, SLOT(generateReport()));
connect(ui->actionToggleBootGuardMarking, SIGNAL(toggled(bool)), this, SLOT(toggleBootGuardMarking(bool))); connect(ui->actionToggleBootGuardMarking, SIGNAL(toggled(bool)), this, SLOT(toggleBootGuardMarking(bool)));
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings())); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings()));
// Enable Drag-and-Drop actions // Enable Drag-and-Drop actions
setAcceptDrops(true); setAcceptDrops(true);
// Disable Builder tab, doesn't work right now
ui->messagesTabWidget->setTabEnabled(4, false);
// Set current directory // Set current directory
currentDir = "."; currentDir = ".";
// Set monospace font for some controls
QFont font("Courier New", 10);
#if defined Q_OS_OSX
font = QFont("Menlo", 10);
#elif defined Q_OS_WIN
font = QFont("Consolas", 9);
#endif
ui->infoEdit->setFont(font);
ui->parserMessagesListWidget->setFont(font);
ui->finderMessagesListWidget->setFont(font);
ui->builderMessagesListWidget->setFont(font);
ui->fitTableWidget->setFont(font);
ui->bootGuardEdit->setFont(font);
ui->structureTreeView->setFont(font);
searchDialog->ui->guidEdit->setFont(font);
searchDialog->ui->hexEdit->setFont(font);
hexViewDialog->setFont(font);
goToOffsetDialog->ui->hexSpinBox->setFont(font);
goToAddressDialog->ui->hexSpinBox->setFont(font);
// Load built-in GUID database // Load built-in GUID database
initGuidDatabase(":/guids.csv"); initGuidDatabase(":/guids.csv");
@ -105,6 +92,7 @@ UEFITool::~UEFITool()
delete ffsOps; delete ffsOps;
delete ffsFinder; delete ffsFinder;
delete ffsParser; delete ffsParser;
delete ffsReport;
delete model; delete model;
delete hexViewDialog; delete hexViewDialog;
delete searchDialog; delete searchDialog;
@ -171,8 +159,9 @@ void UEFITool::init()
void UEFITool::populateUi(const QItemSelection &selected) void UEFITool::populateUi(const QItemSelection &selected)
{ {
if (selected.isEmpty()) if (selected.isEmpty()) {
return; return;
}
populateUi(selected.indexes().at(0)); populateUi(selected.indexes().at(0));
} }
@ -180,8 +169,9 @@ void UEFITool::populateUi(const QItemSelection &selected)
void UEFITool::populateUi(const QModelIndex &current) void UEFITool::populateUi(const QModelIndex &current)
{ {
// Check sanity // Check sanity
if (!current.isValid()) if (!current.isValid()) {
return; return;
}
UINT8 type = model->type(current); UINT8 type = model->type(current);
UINT8 subtype = model->subtype(current); UINT8 subtype = model->subtype(current);
@ -364,7 +354,7 @@ void UEFITool::goToAddress()
return; return;
UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value(); UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value();
QModelIndex index = model->findByOffset(address - ffsParser->getAddressDiff()); QModelIndex index = model->findByOffset(address - (UINT32)ffsParser->getAddressDiff());
if (index.isValid()) { if (index.isValid()) {
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
@ -384,8 +374,8 @@ void UEFITool::goToData()
if (model->hasEmptyParsingData(index)) if (model->hasEmptyParsingData(index))
continue; continue;
UByteArray data = model->parsingData(index); UByteArray rdata = model->parsingData(index);
const NVAR_ENTRY_PARSING_DATA* pdata = (const NVAR_ENTRY_PARSING_DATA*)data.constData(); const NVAR_ENTRY_PARSING_DATA* pdata = (const NVAR_ENTRY_PARSING_DATA*)rdata.constData();
UINT32 lastVariableFlag = pdata->emptyByte ? 0xFFFFFF : 0; UINT32 lastVariableFlag = pdata->emptyByte ? 0xFFFFFF : 0;
UINT32 offset = model->offset(index); UINT32 offset = model->offset(index);
if (pdata->next == lastVariableFlag) { if (pdata->next == lastVariableFlag) {
@ -622,75 +612,75 @@ void UEFITool::extract(const UINT8 mode)
QString path; QString path;
if (mode == EXTRACT_MODE_AS_IS) { if (mode == EXTRACT_MODE_AS_IS) {
switch (type) { switch (type) {
case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", "Capsule files (*.cap *.bin);;All files (*)"); break; case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", tr("Capsule files (*.cap *.bin);;All files (*)")); break;
case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break;
case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", "Region files (*.rgn *.bin);;All files (*)"); break; case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", tr("Region files (*.rgn *.bin);;All files (*)")); break;
case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", "Padding files (*.pad *.bin);;All files (*)"); break; case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", tr("Padding files (*.pad *.bin);;All files (*)")); break;
case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); break; case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)")); break;
case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", "FFS files (*.ffs *.bin);;All files (*)"); break; case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", tr("FFS files (*.ffs *.bin);;All files (*)")); break;
case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", "Section files (*.sct *.bin);;All files (*)"); break; case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", tr("Section files (*.sct *.bin);;All files (*)")); break;
case Types::NvarEntry: path = QFileDialog::getSaveFileName(this, tr("Save NVAR entry to file"), name + ".nvar", "NVAR entry files (*.nvar *.bin);;All files (*)"); break; case Types::NvarEntry: path = QFileDialog::getSaveFileName(this, tr("Save NVAR entry to file"), name + ".nvar", tr("NVAR entry files (*.nvar *.bin);;All files (*)")); break;
case Types::VssEntry: path = QFileDialog::getSaveFileName(this, tr("Save VSS entry to file"), name + ".vss", "VSS entry files (*.vss *.bin);;All files (*)"); break; case Types::VssEntry: path = QFileDialog::getSaveFileName(this, tr("Save VSS entry to file"), name + ".vss", tr("VSS entry files (*.vss *.bin);;All files (*)")); break;
case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", "Fsys entry files (*.fse *.bin);;All files (*)"); break; case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", tr("Fsys entry files (*.fse *.bin);;All files (*)")); break;
case Types::EvsaEntry: path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", "EVSA entry files (*.evse *.bin);;All files (*)"); break; case Types::EvsaEntry: path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", tr("EVSA entry files (*.evse *.bin);;All files (*)")); break;
case Types::FlashMapEntry: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", "FlashMap entry files (*.fme *.bin);;All files (*)"); break; case Types::FlashMapEntry: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", tr("FlashMap entry files (*.fme *.bin);;All files (*)")); break;
case Types::VssStore: path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", "VSS store files (*.vss *.bin);;All files (*)"); break; case Types::VssStore: path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", tr("VSS store files (*.vss *.bin);;All files (*)")); break;
case Types::Vss2Store: path = QFileDialog::getSaveFileName(this, tr("Save VSS2 store to file"), name + ".vss2", "VSS2 store files (*.vss2 *.bin);;All files (*)"); break; case Types::Vss2Store: path = QFileDialog::getSaveFileName(this, tr("Save VSS2 store to file"), name + ".vss2", tr("VSS2 store files (*.vss2 *.bin);;All files (*)")); break;
case Types::FdcStore: path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", "FDC store files (*.fdc *.bin);;All files (*)"); break; case Types::FdcStore: path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", tr("FDC store files (*.fdc *.bin);;All files (*)")); break;
case Types::FsysStore: path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", "Fsys store files (*.fsys *.bin);;All files (*)"); break; case Types::FsysStore: path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", tr("Fsys store files (*.fsys *.bin);;All files (*)")); break;
case Types::EvsaStore: path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", "EVSA store files (*.evsa *.bin);;All files (*)"); break; case Types::EvsaStore: path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", tr("EVSA store files (*.evsa *.bin);;All files (*)")); break;
case Types::FtwStore: path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", "FTW store files (*.ftw *.bin);;All files (*)"); break; case Types::FtwStore: path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", tr("FTW store files (*.ftw *.bin);;All files (*)")); break;
case Types::FlashMapStore: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", "FlashMap store files (*.fmap *.bin);;All files (*)"); break; case Types::FlashMapStore: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", tr("FlashMap store files (*.fmap *.bin);;All files (*)")); break;
case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save CMDB store to file"), name + ".cmdb", "CMDB store files (*.cmdb *.bin);;All files (*)"); break; case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save CMDB store to file"), name + ".cmdb", tr("CMDB store files (*.cmdb *.bin);;All files (*)")); break;
case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode binary to file"), name + ".ucd", "Microcode binary files (*.ucd *.bin);;All files (*)"); break; case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode binary to file"), name + ".ucd", tr("Microcode binary files (*.ucd *.bin);;All files (*)")); break;
case Types::SlicData: case Types::SlicData:
if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", "SLIC pubkey files (*.spk *.bin);;All files (*)"); if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", tr("SLIC pubkey files (*.spk *.bin);;All files (*)"));
else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", "SLIC marker files (*.smk *.bin);;All files (*)"); else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", tr("SLIC marker files (*.smk *.bin);;All files (*)"));
break; break;
default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)"));
} }
} }
else if (mode == EXTRACT_MODE_BODY || mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { else if (mode == EXTRACT_MODE_BODY || mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
switch (type) { switch (type) {
case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break;
case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", "Volume body files (*.vbd *.bin);;All files (*)"); break; case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", tr("Volume body files (*.vbd *.bin);;All files (*)")); break;
case Types::File: case Types::File:
if (subtype == EFI_FV_FILETYPE_ALL if (subtype == EFI_FV_FILETYPE_ALL
|| subtype == EFI_FV_FILETYPE_RAW) path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); || subtype == EFI_FV_FILETYPE_RAW) path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", tr("Raw files (*.raw *.bin);;All files (*)"));
else path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); else path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", tr("FFS file body files (*.fbd *.bin);;All files (*)"));
break; break;
case Types::Section: case Types::Section:
if (subtype == EFI_SECTION_COMPRESSION if (subtype == EFI_SECTION_COMPRESSION
|| subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_GUID_DEFINED
|| subtype == EFI_SECTION_DISPOSABLE) path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); || subtype == EFI_SECTION_DISPOSABLE) path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", tr("FFS file body files (*.fbd *.bin);;All files (*)"));
else if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); else if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)"));
else if (subtype == EFI_SECTION_RAW) path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); else if (subtype == EFI_SECTION_RAW) path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", tr("Raw files (*.raw *.bin);;All files (*)"));
else if (subtype == EFI_SECTION_PE32 else if (subtype == EFI_SECTION_PE32
|| subtype == EFI_SECTION_TE || subtype == EFI_SECTION_TE
|| subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", "EFI executable files (*.efi *.bin);;All files (*)"); || subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", tr("EFI executable files (*.efi *.bin);;All files (*)"));
else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)"));
break; break;
case Types::NvarEntry: case Types::NvarEntry:
case Types::VssEntry: case Types::VssEntry:
case Types::EvsaEntry: case Types::EvsaEntry:
case Types::FlashMapEntry: case Types::FlashMapEntry:
case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break;
case Types::VssStore: case Types::VssStore:
case Types::Vss2Store: case Types::Vss2Store:
case Types::FtwStore: case Types::FtwStore:
case Types::FdcStore: case Types::FdcStore:
case Types::FsysStore: case Types::FsysStore:
case Types::FlashMapStore: case Types::FlashMapStore:
case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break;
case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", "Microcode body files (*.ucb *.bin);;All files (*)"); break; case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", tr("Microcode body files (*.ucb *.bin);;All files (*)")); break;
case Types::SlicData: case Types::SlicData:
if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", "SLIC pubkey body files (*.spb *.bin);;All files (*)"); if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", tr("SLIC pubkey body files (*.spb *.bin);;All files (*)"));
else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", "SLIC marker body files (*.smb *.bin);;All files (*)"); else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", tr("SLIC marker body files (*.smb *.bin);;All files (*)"));
break; break;
default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)"));
} }
} }
else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)"));
if (path.trimmed().isEmpty()) if (path.trimmed().isEmpty())
return; return;
@ -733,7 +723,7 @@ void UEFITool::remove()
void UEFITool::about() void UEFITool::about()
{ {
QMessageBox::about(this, tr("About UEFITool"), tr( QMessageBox::about(this, tr("About UEFITool"), tr(
"Copyright (c) 2016, Nikolaj Schlej aka <b>CodeRush</b>.<br>" "Copyright (c) 2018, LongSoft"
"Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br>" "Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br>"
"The program uses QHexEdit2 library made by <a href=https://github.com/Simsys/>Simsys</a>.<br>" "The program uses QHexEdit2 library made by <a href=https://github.com/Simsys/>Simsys</a>.<br>"
"Qt-less engine is using Bstrlib made by <a href=https://github.com/websnarf/>Paul Hsieh</a>.<br><br>" "Qt-less engine is using Bstrlib made by <a href=https://github.com/websnarf/>Paul Hsieh</a>.<br><br>"
@ -757,7 +747,7 @@ void UEFITool::exit()
void UEFITool::saveImageFile() void UEFITool::saveImageFile()
{ {
/*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)"); /*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)"));
if (path.isEmpty()) if (path.isEmpty())
return; return;
@ -790,13 +780,13 @@ void UEFITool::saveImageFile()
void UEFITool::openImageFile() void UEFITool::openImageFile()
{ {
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"));
openImageFile(path); openImageFile(path);
} }
void UEFITool::openImageFileInNewWindow() void UEFITool::openImageFileInNewWindow()
{ {
QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"));
if (path.trimmed().isEmpty()) if (path.trimmed().isEmpty())
return; return;
QProcess::startDetached(currentProgramPath, QStringList(path)); QProcess::startDetached(currentProgramPath, QStringList(path));
@ -848,12 +838,18 @@ void UEFITool::openImageFile(QString path)
// ... and other operations // ... and other operations
delete ffsOps; delete ffsOps;
ffsOps = new FfsOperations(model); ffsOps = new FfsOperations(model);
// ... and reports
delete ffsReport;
ffsReport = new FfsReport(model);
// Enable goToOffset and goToAddress // Enable goToOffset and goToAddress
ui->actionGoToOffset->setEnabled(true); ui->actionGoToOffset->setEnabled(true);
if (ffsParser->getAddressDiff() < 0xFFFFFFFFUL) if (ffsParser->getAddressDiff() < 0xFFFFFFFFUL)
ui->actionGoToAddress->setEnabled(true); ui->actionGoToAddress->setEnabled(true);
// Enable generateReport
ui->actionGenerateReport->setEnabled(true);
// Set current directory // Set current directory
currentDir = fileInfo.absolutePath(); currentDir = fileInfo.absolutePath();
@ -1023,13 +1019,15 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
return; return;
} }
if (!ui->structureTreeView->underMouse()) if (!ui->structureTreeView->underMouse()) {
return; return;
}
QPoint pt = event->pos(); QPoint pt = event->pos();
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
if (!index.isValid()) if (!index.isValid()) {
return; return;
}
switch (model->type(index)) switch (model->type(index))
{ {
@ -1075,6 +1073,34 @@ void UEFITool::readSettings()
ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt());
ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt());
markingEnabled = settings.value("tree/markingEnabled", true).toBool(); markingEnabled = settings.value("tree/markingEnabled", true).toBool();
ui->actionToggleBootGuardMarking->setChecked(markingEnabled);
// Set monospace font for some controls
QString fontName;
int fontSize;
#if defined Q_OS_OSX
fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString();
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
#elif defined Q_OS_WIN
fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString();
fontSize = settings.value("mainWindow/fontSize", 9).toInt();
#else
fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString();
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
#endif
currentFont = QFont(fontName, fontSize);
ui->infoEdit->setFont(currentFont);
ui->parserMessagesListWidget->setFont(currentFont);
ui->finderMessagesListWidget->setFont(currentFont);
ui->builderMessagesListWidget->setFont(currentFont);
ui->fitTableWidget->setFont(currentFont);
ui->bootGuardEdit->setFont(currentFont);
ui->structureTreeView->setFont(currentFont);
searchDialog->ui->guidEdit->setFont(currentFont);
searchDialog->ui->hexEdit->setFont(currentFont);
hexViewDialog->setFont(currentFont);
goToOffsetDialog->ui->hexSpinBox->setFont(currentFont);
goToAddressDialog->ui->hexSpinBox->setFont(currentFont);
} }
void UEFITool::writeSettings() void UEFITool::writeSettings()
@ -1091,6 +1117,8 @@ void UEFITool::writeSettings()
settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2));
settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3));
settings.setValue("tree/markingEnabled", markingEnabled); settings.setValue("tree/markingEnabled", markingEnabled);
settings.setValue("mainWindow/fontName", currentFont.family());
settings.setValue("mainWindow/fontSize", currentFont.pointSize());
} }
void UEFITool::showFitTable() void UEFITool::showFitTable()
@ -1155,10 +1183,44 @@ void UEFITool::currentTabChanged(int index)
void UEFITool::loadGuidDatabase() void UEFITool::loadGuidDatabase()
{ {
QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, "GUID database files (*.gdb);;All files (*)"); QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)"));
if (!path.isEmpty()) { if (!path.isEmpty()) {
initGuidDatabase(path); 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)) 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); openImageFile(currentPath);
} }
} }
void UEFITool::unloadGuidDatabase()
{
initGuidDatabase();
if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("GUID database unloaded"), tr("Apply changes on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No))
openImageFile(currentPath);
}
void UEFITool::loadDefaultGuidDatabase()
{
initGuidDatabase(":/guids.csv");
if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("Default GUID database loaded"), tr("Apply default GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No))
openImageFile(currentPath);
}
void UEFITool::generateReport()
{
QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)"));
if (!path.isEmpty()) {
std::vector<QString> report = ffsReport->generate();
if (report.size()) {
QFile file;
file.setFileName(path);
if (file.open(QFile::Text | QFile::WriteOnly)) {
for (size_t i = 0; i < report.size(); i++) {
file.write(report[i].toLatin1().append('\n'));
}
file.close();
}
}
}
}

View file

@ -22,6 +22,7 @@
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QFileInfo> #include <QFileInfo>
#include <QFont>
#include <QListWidget> #include <QListWidget>
#include <QMenu> #include <QMenu>
#include <QMessageBox> #include <QMessageBox>
@ -41,6 +42,7 @@
#include "../common/ffsparser.h" #include "../common/ffsparser.h"
#include "../common/ffsops.h" #include "../common/ffsops.h"
#include "../common/ffsbuilder.h" #include "../common/ffsbuilder.h"
#include "../common/ffsreport.h"
#include "../common/guiddatabase.h" #include "../common/guiddatabase.h"
#include "searchdialog.h" #include "searchdialog.h"
@ -115,6 +117,9 @@ private slots:
void writeSettings(); void writeSettings();
void loadGuidDatabase(); void loadGuidDatabase();
void unloadGuidDatabase();
void loadDefaultGuidDatabase();
void generateReport();
void currentTabChanged(int index); void currentTabChanged(int index);
@ -123,6 +128,7 @@ private:
TreeModel* model; TreeModel* model;
FfsParser* ffsParser; FfsParser* ffsParser;
FfsFinder* ffsFinder; FfsFinder* ffsFinder;
FfsReport* ffsReport;
FfsOperations* ffsOps; FfsOperations* ffsOps;
FfsBuilder* ffsBuilder; FfsBuilder* ffsBuilder;
SearchDialog* searchDialog; SearchDialog* searchDialog;
@ -133,6 +139,7 @@ private:
QString currentDir; QString currentDir;
QString currentPath; QString currentPath;
QString currentProgramPath; QString currentProgramPath;
QFont currentFont;
const QString version; const QString version;
bool markingEnabled; bool markingEnabled;

View file

@ -32,6 +32,7 @@ HEADERS += uefitool.h \
../common/parsingdata.h \ ../common/parsingdata.h \
../common/ffsbuilder.h \ ../common/ffsbuilder.h \
../common/ffsparser.h \ ../common/ffsparser.h \
../common/ffsreport.h \
../common/treeitem.h \ ../common/treeitem.h \
../common/treemodel.h \ ../common/treemodel.h \
../common/LZMA/LzmaCompress.h \ ../common/LZMA/LzmaCompress.h \
@ -64,6 +65,7 @@ SOURCES += uefitool_main.cpp \
../common/utility.cpp \ ../common/utility.cpp \
../common/ffsbuilder.cpp \ ../common/ffsbuilder.cpp \
../common/ffsparser.cpp \ ../common/ffsparser.cpp \
../common/ffsreport.cpp \
../common/treeitem.cpp \ ../common/treeitem.cpp \
../common/treemodel.cpp \ ../common/treemodel.cpp \
../common/LZMA/LzmaCompress.c \ ../common/LZMA/LzmaCompress.c \

View file

@ -322,7 +322,11 @@
<addaction name="actionOpenImageFileInNewWindow"/> <addaction name="actionOpenImageFileInNewWindow"/>
<addaction name="actionSaveImageFile"/> <addaction name="actionSaveImageFile"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionGenerateReport"/>
<addaction name="separator"/>
<addaction name="actionLoadGuidDatabase"/> <addaction name="actionLoadGuidDatabase"/>
<addaction name="actionLoadDefaultGuidDatabase"/>
<addaction name="actionUnloadGuidDatabase"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
</widget> </widget>
@ -473,7 +477,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="title"> <property name="title">
<string>Entry</string> <string>&amp;Entry</string>
</property> </property>
<addaction name="actionHexView"/> <addaction name="actionHexView"/>
<addaction name="actionBodyHexView"/> <addaction name="actionBodyHexView"/>
@ -532,7 +536,7 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="menuMessageActions"/> <addaction name="menuMessageActions"/>
</widget> </widget>
<widget class="QMenu" name="menu_View"> <widget class="QMenu" name="menuView">
<property name="title"> <property name="title">
<string>&amp;View</string> <string>&amp;View</string>
</property> </property>
@ -540,7 +544,7 @@
</widget> </widget>
<addaction name="menuFile"/> <addaction name="menuFile"/>
<addaction name="menuAction"/> <addaction name="menuAction"/>
<addaction name="menu_View"/> <addaction name="menuView"/>
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<action name="actionInsertAfter"> <action name="actionInsertAfter">
@ -718,7 +722,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Sear&amp;ch...</string> <string>Searc&amp;h...</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+F</string> <string>Ctrl+F</string>
@ -867,12 +871,42 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;BootGuard marking</string> <string>BootGuard &amp;markings</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+Shift+B</string> <string>Ctrl+Shift+B</string>
</property> </property>
</action> </action>
<action name="actionGenerateReport">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Generate &amp;report...</string>
</property>
<property name="toolTip">
<string>Generate report</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+R</string>
</property>
</action>
<action name="actionUnloadGuidDatabase">
<property name="text">
<string>&amp;Unload GUID database</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+U</string>
</property>
</action>
<action name="actionLoadDefaultGuidDatabase">
<property name="text">
<string>Load &amp;default GUID database</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+D</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources/> <resources/>

View file

@ -1,6 +1,6 @@
/* uefitool_main.cpp /* uefitool_main.cpp
Copyright (c) 2014, Nikolaj Schlej. All rights reserved. Copyright (c) 2018, LongSoft. All rights reserved.
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at

View file

@ -25,7 +25,7 @@ static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize) SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize)
{ {
(void)p; (void) inSize; (void) outSize; (void)p; (void)inSize; (void)outSize;
return SZ_OK; return SZ_OK;
} }
@ -34,9 +34,9 @@ static ICompressProgress g_ProgressCallback = { &OnProgress };
STATIC STATIC
UINT64 UINT64
EFIAPI EFIAPI
RShiftU64( RShiftU64 (
UINT64 Operand, UINT64 Operand,
UINT32 Count UINT32 Count
) )
{ {
return Operand >> Count; return Operand >> Count;
@ -44,8 +44,8 @@ UINT32 Count
VOID VOID
SetEncodedSizeOfBuf( SetEncodedSizeOfBuf(
UINT64 EncodedSize, UINT64 EncodedSize,
UINT8 *EncodedData UINT8* EncodedData
) )
{ {
INT32 Index; INT32 Index;
@ -58,13 +58,13 @@ UINT8 *EncodedData
} }
} }
INT32 USTATUS
EFIAPI EFIAPI
LzmaCompress( LzmaCompress (
CONST UINT8 *Source, CONST UINT8 *Source,
UINT32 SourceSize, UINT32 SourceSize,
UINT8 *Destination, UINT8 *Destination,
UINT32 *DestinationSize UINT32 *DestinationSize
) )
{ {
SRes LzmaResult; SRes LzmaResult;
@ -72,13 +72,14 @@ UINT32 *DestinationSize
SizeT propsSize = LZMA_PROPS_SIZE; SizeT propsSize = LZMA_PROPS_SIZE;
SizeT destLen = SourceSize + SourceSize / 3 + 128; SizeT destLen = SourceSize + SourceSize / 3 + 128;
if (*DestinationSize < destLen) if (*DestinationSize < (UINT32)destLen)
{ {
*DestinationSize = (UINT32)destLen; *DestinationSize = (UINT32)destLen;
return EFI_BUFFER_TOO_SMALL; return EFI_BUFFER_TOO_SMALL;
} }
LzmaEncProps_Init(&props); LzmaEncProps_Init(&props);
// TODO: need to detect this instead of hardcoding
props.dictSize = LZMA_DICTIONARY_SIZE; props.dictSize = LZMA_DICTIONARY_SIZE;
props.level = 9; props.level = 9;
props.fb = 273; props.fb = 273;
@ -87,7 +88,7 @@ UINT32 *DestinationSize
(Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE),
&destLen, &destLen,
Source, Source,
SourceSize, (SizeT)SourceSize,
&props, &props,
(UINT8*)Destination, (UINT8*)Destination,
&propsSize, &propsSize,
@ -98,7 +99,7 @@ UINT32 *DestinationSize
*DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE); *DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE);
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); SetEncodedSizeOfBuf(SourceSize, Destination);
if (LzmaResult == SZ_OK) { if (LzmaResult == SZ_OK) {
return EFI_SUCCESS; return EFI_SUCCESS;

View file

@ -24,13 +24,13 @@ extern "C" {
#define LZMA_DICTIONARY_SIZE 0x800000 #define LZMA_DICTIONARY_SIZE 0x800000
#define _LZMA_SIZE_OPT #define _LZMA_SIZE_OPT
INT32 USTATUS
EFIAPI EFIAPI
LzmaCompress( LzmaCompress (
const UINT8 *Source, const UINT8 *Source,
UINT32 SourceSize, UINT32 SourceSize,
UINT8 *Destination, UINT8 *Destination,
UINT32 *DestinationSize UINT32 *DestinationSize
); );
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -19,10 +19,10 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT64 UINT64
EFIAPI EFIAPI
LShiftU64( LShiftU64 (
UINT64 Operand, UINT64 Operand,
UINT32 Count UINT32 Count
) )
{ {
return Operand << Count; return Operand << Count;
} }
@ -39,12 +39,12 @@ Get the size of the uncompressed buffer by parsing EncodeData header.
@return The size of the uncompressed buffer. @return The size of the uncompressed buffer.
*/ */
UINT64 UINT64
GetDecodedSizeOfBuf( GetDecodedSizeOfBuf (
UINT8 *EncodedData UINT8 *EncodedData
) )
{ {
UINT64 DecodedSize; UINT64 DecodedSize;
INT32 Index; INT32 Index;
// Parse header // Parse header
DecodedSize = 0; DecodedSize = 0;
@ -85,22 +85,27 @@ DestinationSize and the size of the scratch
buffer was returned ScratchSize. buffer was returned ScratchSize.
*/ */
INT32 USTATUS
EFIAPI EFIAPI
LzmaGetInfo( LzmaGetInfo (
CONST VOID *Source, CONST VOID *Source,
UINT32 SourceSize, UINT32 SourceSize,
UINT32 *DestinationSize UINT32 *DestinationSize
) )
{ {
UInt64 DecodedSize; UINT64 DecodedSize;
ASSERT(SourceSize >= LZMA_HEADER_SIZE);
(void)SourceSize;
ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize;
DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);
*DestinationSize = (UINT32)DecodedSize; if (DecodedSize <= UINT32_MAX) {
return U_SUCCESS; *DestinationSize = (UINT32)DecodedSize;
return U_SUCCESS;
}
else {
return U_INVALID_PARAMETER;
}
} }
/* /*
@ -122,13 +127,13 @@ the uncompressed buffer is returned Destination.
The source buffer specified by Source is corrupted The source buffer specified by Source is corrupted
(not a valid compressed format). (not a valid compressed format).
*/ */
INT32 USTATUS
EFIAPI EFIAPI
LzmaDecompress( LzmaDecompress (
CONST VOID *Source, CONST VOID *Source,
UINT32 SourceSize, UINT32 SourceSize,
VOID *Destination VOID *Destination
) )
{ {
SRes LzmaResult; SRes LzmaResult;
ELzmaStatus Status; ELzmaStatus Status;

View file

@ -23,13 +23,6 @@ extern "C" {
#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
UINT64
EFIAPI
LShiftU64(
UINT64 Operand,
UINT32 Count
);
/* /*
Given a Lzma compressed source buffer, this function retrieves the size of Given a Lzma compressed source buffer, this function retrieves the size of
the uncompressed buffer and the size of the scratch buffer required the uncompressed buffer and the size of the scratch buffer required
@ -57,12 +50,12 @@ extern "C" {
buffer was returned ScratchSize. buffer was returned ScratchSize.
*/ */
INT32 USTATUS
EFIAPI EFIAPI
LzmaGetInfo( LzmaGetInfo (
const VOID *Source, CONST VOID *Source,
UINT32 SourceSize, UINT32 SourceSize,
UINT32 *DestinationSize UINT32 *DestinationSize
); );
/* /*
@ -84,12 +77,12 @@ extern "C" {
The source buffer specified by Source is corrupted The source buffer specified by Source is corrupted
(not a valid compressed format). (not a valid compressed format).
*/ */
INT32 USTATUS
EFIAPI EFIAPI
LzmaDecompress( LzmaDecompress (
const VOID *Source, CONST VOID *Source,
UINT32 SourceSize, UINT32 SourceSize,
VOID *Destination VOID *Destination
); );
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -69,18 +69,15 @@ PutDword(
STATIC STATIC
EFI_STATUS EFI_STATUS
AllocateMemory ( AllocateMemory (VOID);
);
STATIC STATIC
VOID VOID
FreeMemory ( FreeMemory (VOID);
);
STATIC STATIC
VOID VOID
InitSlide ( InitSlide (VOID);
);
STATIC STATIC
NODE NODE
@ -105,28 +102,23 @@ Split (
STATIC STATIC
VOID VOID
InsertNode ( InsertNode (VOID);
);
STATIC STATIC
VOID VOID
DeleteNode ( DeleteNode (VOID);
);
STATIC STATIC
VOID VOID
GetNextMatch ( GetNextMatch (VOID);
);
STATIC STATIC
EFI_STATUS EFI_STATUS
Encode ( Encode (VOID);
);
STATIC STATIC
VOID VOID
CountTFreq ( CountTFreq (VOID);
);
STATIC STATIC
VOID VOID
@ -138,8 +130,7 @@ WritePTLen (
STATIC STATIC
VOID VOID
WriteCLen ( WriteCLen (VOID);
);
STATIC STATIC
VOID VOID
@ -155,8 +146,7 @@ EncodeP (
STATIC STATIC
VOID VOID
SendBlock ( SendBlock (VOID);
);
STATIC STATIC
VOID VOID
@ -167,18 +157,15 @@ Output (
STATIC STATIC
VOID VOID
HufEncodeStart ( HufEncodeStart (VOID);
);
STATIC STATIC
VOID VOID
HufEncodeEnd ( HufEncodeEnd (VOID);
);
STATIC STATIC
VOID VOID
MakeCrcTable ( MakeCrcTable (VOID);
);
STATIC STATIC
VOID VOID
@ -196,8 +183,7 @@ FreadCrc (
STATIC STATIC
VOID VOID
InitPutBits ( InitPutBits (VOID);
);
STATIC STATIC
VOID VOID

View file

@ -56,22 +56,20 @@ extern "C" {
--*/ --*/
EFI_STATUS EFI_STATUS
TianoCompress( TianoCompress (
CONST VOID *SrcBuffer, IN CONST VOID *SrcBuffer,
UINT32 SrcSize, IN UINT32 SrcSize,
VOID *DstBuffer, IN VOID *DstBuffer,
UINT32 *DstSize IN OUT UINT32 *DstSize
) );
;
EFI_STATUS EFI_STATUS
TianoCompressLegacy( TianoCompressLegacy(
CONST VOID *SrcBuffer, CONST VOID *SrcBuffer,
UINT32 SrcSize, UINT32 SrcSize,
VOID *DstBuffer, VOID *DstBuffer,
UINT32 *DstSize UINT32 *DstSize
) );
;
/*++ /*++
Routine Description: Routine Description:
@ -96,21 +94,20 @@ extern "C" {
--*/ --*/
EFI_STATUS EFI_STATUS
EfiCompress( EfiCompress (
CONST VOID *SrcBuffer, IN CONST VOID *SrcBuffer,
UINT32 SrcSize, IN UINT32 SrcSize,
VOID *DstBuffer, IN VOID *DstBuffer,
UINT32 *DstSize IN OUT UINT32 *DstSize
) );
;
EFI_STATUS EFI_STATUS
EfiCompressLegacy( EfiCompressLegacy(
CONST VOID *SrcBuffer, CONST VOID *SrcBuffer,
UINT32 SrcSize, UINT32 SrcSize,
VOID *DstBuffer, VOID *DstBuffer,
UINT32 *DstSize UINT32 *DstSize
) );
;
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -79,12 +79,6 @@ typedef struct {
UINT8 mPBit; UINT8 mPBit;
} SCRATCH_DATA; } SCRATCH_DATA;
STATIC
VOID
FillBuf(
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
/*++ /*++
Routine Description: Routine Description:
@ -99,11 +93,17 @@ NumOfBits - The number of bits to shift and read.
Returns: (VOID) Returns: (VOID)
--*/ --*/
STATIC
VOID
FillBuf (
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
{ {
Sd->mBitBuf = (UINT32)(Sd->mBitBuf << NumOfBits); Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
while (NumOfBits > Sd->mBitCount) { while (NumOfBits > Sd->mBitCount) {
Sd->mBitBuf |= (UINT32)(Sd->mSubBitBuf << (NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount))); Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
if (Sd->mCompSize > 0) { if (Sd->mCompSize > 0) {
// //
@ -127,12 +127,6 @@ Returns: (VOID)
Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount; Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
} }
STATIC
UINT32
GetBits(
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
/*++ /*++
Routine Description: Routine Description:
@ -151,6 +145,12 @@ Returns:
The bits that are popped out. The bits that are popped out.
--*/ --*/
STATIC
UINT32
GetBits (
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
{ {
UINT32 OutBits; UINT32 OutBits;
@ -161,15 +161,6 @@ The bits that are popped out.
return OutBits; return OutBits;
} }
STATIC
UINT16
MakeTable(
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfChar,
IN UINT8 *BitLen,
IN UINT16 TableBits,
OUT UINT16 *Table
)
/*++ /*++
Routine Description: Routine Description:
@ -190,6 +181,15 @@ Returns:
BAD_TABLE - The table is corrupted. BAD_TABLE - The table is corrupted.
--*/ --*/
STATIC
UINT16
MakeTable (
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfChar,
IN UINT8 *BitLen,
IN UINT16 TableBits,
OUT UINT16 *Table
)
{ {
UINT16 Count[17]; UINT16 Count[17];
UINT16 Weight[17]; UINT16 Weight[17];
@ -321,11 +321,6 @@ BAD_TABLE - The table is corrupted.
return 0; return 0;
} }
STATIC
UINT32
DecodeP(
IN SCRATCH_DATA *Sd
)
/*++ /*++
Routine Description: Routine Description:
@ -341,6 +336,11 @@ Returns:
The position value decoded. The position value decoded.
--*/ --*/
STATIC
UINT32
DecodeP (
IN SCRATCH_DATA *Sd
)
{ {
UINT16 Val; UINT16 Val;
UINT32 Mask; UINT32 Mask;
@ -375,14 +375,6 @@ The position value decoded.
return Pos; return Pos;
} }
STATIC
UINT16
ReadPTLen(
IN SCRATCH_DATA *Sd,
IN UINT16 nn,
IN UINT16 nbit,
IN UINT16 Special
)
/*++ /*++
Routine Description: Routine Description:
@ -402,6 +394,14 @@ Returns:
BAD_TABLE - Table is corrupted. BAD_TABLE - Table is corrupted.
--*/ --*/
STATIC
UINT16
ReadPTLen (
IN SCRATCH_DATA *Sd,
IN UINT16 nn,
IN UINT16 nbit,
IN UINT16 Special
)
{ {
UINT16 Number; UINT16 Number;
UINT16 CharC; UINT16 CharC;
@ -469,11 +469,6 @@ BAD_TABLE - Table is corrupted.
return MakeTable(Sd, nn, Sd->mPTLen, 8, Sd->mPTTable); return MakeTable(Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);
} }
STATIC
VOID
ReadCLen(
SCRATCH_DATA *Sd
)
/*++ /*++
Routine Description: Routine Description:
@ -487,6 +482,11 @@ Sd - the global scratch data
Returns: (VOID) Returns: (VOID)
--*/ --*/
STATIC
VOID
ReadCLen (
SCRATCH_DATA *Sd
)
{ {
UINT16 Number; UINT16 Number;
UINT16 CharC; UINT16 CharC;
@ -560,11 +560,6 @@ Returns: (VOID)
return; return;
} }
STATIC
UINT16
DecodeC(
SCRATCH_DATA *Sd
)
/*++ /*++
Routine Description: Routine Description:
@ -580,6 +575,11 @@ Returns:
The value decoded. The value decoded.
--*/ --*/
STATIC
UINT16
DecodeC (
SCRATCH_DATA *Sd
)
{ {
UINT16 Index2; UINT16 Index2;
UINT32 Mask; UINT32 Mask;
@ -627,11 +627,6 @@ The value decoded.
return Index2; return Index2;
} }
STATIC
VOID
Decode(
SCRATCH_DATA *Sd
)
/*++ /*++
Routine Description: Routine Description:
@ -645,6 +640,11 @@ Sd - The global scratch data
Returns: (VOID) Returns: (VOID)
--*/ --*/
STATIC
VOID
Decode (
SCRATCH_DATA *Sd
)
{ {
UINT16 BytesRemain; UINT16 BytesRemain;
UINT32 DataIdx; UINT32 DataIdx;
@ -700,13 +700,6 @@ Returns: (VOID)
} }
} }
EFI_STATUS
GetInfo(
IN const VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
/*++ /*++
Routine Description: Routine Description:
@ -726,6 +719,13 @@ EFI_SUCCESS - The size of destination buffer and the size of scratch b
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
EFI_STATUS
GetInfo(
IN const VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
{ {
const UINT8 *Src; const UINT8 *Src;
@ -740,16 +740,6 @@ EFI_INVALID_PARAMETER - The source data is corrupted
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS
Decompress(
IN const VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize,
IN UINT8 Version
)
/*++ /*++
Routine Description: Routine Description:
@ -774,6 +764,16 @@ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
EFI_STATUS
Decompress (
IN CONST VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize,
IN UINT8 Version
)
{ {
UINT32 Index; UINT32 Index;
UINT32 CompSize; UINT32 CompSize;
@ -866,14 +866,6 @@ EFI_INVALID_PARAMETER - The source data is corrupted
return Status; return Status;
} }
EFI_STATUS
EFIAPI
EfiTianoGetInfo(
IN const VOID *Source,
IN UINT32 SrcSize,
OUT UINT32 *DstSize,
OUT UINT32 *ScratchSize
)
/*++ /*++
Routine Description: Routine Description:
@ -894,25 +886,18 @@ EFI_SUCCESS - The size of destination buffer and the size of scratch b
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
{
return GetInfo(
Source,
SrcSize,
DstSize,
ScratchSize
);
}
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
EfiDecompress( EfiTianoGetInfo(
IN const VOID *Source, IN CONST VOID *Source,
IN UINT32 SrcSize, IN UINT32 SrcSize,
IN OUT VOID *Destination, OUT UINT32 *DstSize,
IN UINT32 DstSize, OUT UINT32 *ScratchSize
IN OUT VOID *Scratch, )
IN UINT32 ScratchSize {
) return GetInfo (Source, SrcSize, DstSize, ScratchSize);
}
/*++ /*++
Routine Description: Routine Description:
@ -935,11 +920,21 @@ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
EFI_STATUS
EFIAPI
EfiDecompress (
IN CONST VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize
)
{ {
// //
// For EFI 1.1 de/compression algorithm, the version is 1. // For EFI 1.1 de/compression algorithm, the version is 1.
// //
return Decompress( return Decompress (
Source, Source,
SrcSize, SrcSize,
Destination, Destination,
@ -950,16 +945,6 @@ EFI_INVALID_PARAMETER - The source data is corrupted
); );
} }
EFI_STATUS
EFIAPI
TianoDecompress(
IN const VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize
)
/*++ /*++
Routine Description: Routine Description:
@ -982,11 +967,21 @@ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
EFI_STATUS
EFIAPI
TianoDecompress (
IN CONST VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize
)
{ {
// //
// For Tiano de/compression algorithm, the version is 2. // For Tiano de/compression algorithm, the version is 2.
// //
return Decompress( return Decompress (
Source, Source,
SrcSize, SrcSize,
Destination, Destination,

View file

@ -37,14 +37,6 @@ typedef struct EFI_TIANO_HEADER_ {
UINT32 OrigSize; UINT32 OrigSize;
} EFI_TIANO_HEADER; } EFI_TIANO_HEADER;
EFI_STATUS
EFIAPI
EfiTianoGetInfo(
const VOID *Source,
UINT32 SrcSize,
UINT32 *DstSize,
UINT32 *ScratchSize
)
/*++ /*++
Routine Description: Routine Description:
@ -64,18 +56,16 @@ EFI_SUCCESS - The size of destination buffer and the size of scratch b
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
EfiDecompress( EfiTianoGetInfo (
const VOID *Source, IN CONST VOID *Source,
UINT32 SrcSize, IN UINT32 SrcSize,
VOID *Destination, OUT UINT32 *DstSize,
UINT32 DstSize, OUT UINT32 *ScratchSize
VOID *Scratch, );
UINT32 ScratchSize
);
/*++ /*++
Routine Description: Routine Description:
@ -97,18 +87,17 @@ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
TianoDecompress( EfiDecompress(
const VOID *Source, IN CONST VOID *Source,
UINT32 SrcSize, IN UINT32 SrcSize,
VOID *Destination, IN OUT VOID *Destination,
UINT32 DstSize, IN UINT32 DstSize,
VOID *Scratch, IN OUT VOID *Scratch,
UINT32 ScratchSize IN UINT32 ScratchSize
) );
/*++ /*++
Routine Description: Routine Description:
@ -130,7 +119,16 @@ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted EFI_INVALID_PARAMETER - The source data is corrupted
--*/ --*/
; EFI_STATUS
EFIAPI
TianoDecompress(
IN CONST VOID *Source,
IN UINT32 SrcSize,
IN OUT VOID *Destination,
IN UINT32 DstSize,
IN OUT VOID *Scratch,
IN UINT32 ScratchSize
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -16,8 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
typedef uint8_t USTATUS; typedef size_t USTATUS;
#define U_SUCCESS 0 #define U_SUCCESS 0
#define U_INVALID_PARAMETER 1 #define U_INVALID_PARAMETER 1
#define U_BUFFER_TOO_SMALL 2 #define U_BUFFER_TOO_SMALL 2
@ -79,7 +80,7 @@ typedef int64_t INT64;
typedef uint64_t UINT64; typedef uint64_t UINT64;
typedef char CHAR8; typedef char CHAR8;
typedef uint16_t CHAR16; typedef uint16_t CHAR16;
typedef unsigned int UINTN; typedef size_t UINTN;
#define CONST const #define CONST const
#define VOID void #define VOID void
@ -161,11 +162,11 @@ typedef struct EFI_TIME_ {
UINT8 Hour; // Hour: 0 - 23 UINT8 Hour; // Hour: 0 - 23
UINT8 Minute; // Minute: 0 - 59 UINT8 Minute; // Minute: 0 - 59
UINT8 Second; // Second: 0 - 59 UINT8 Second; // Second: 0 - 59
UINT8 : 8; UINT8 Reserved0;
UINT32 Nanosecond; // Nanosecond: 0 - 999,999,999 UINT32 Nanosecond; // Nanosecond: 0 - 999,999,999
INT16 TimeZone; // TimeZone: -1440 to 1440 or UNSPECIFIED (0x07FF) INT16 TimeZone; // TimeZone: -1440 to 1440 or UNSPECIFIED (0x07FF)
UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2) UINT8 Daylight; // Daylight: ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2)
UINT8 : 8; UINT8 Reserved1;
} EFI_TIME; } EFI_TIME;
// Align to 4 or 8 bytes // Align to 4 or 8 bytes

View file

@ -25,13 +25,13 @@ const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLim
return baseAddress + baseOrLimit * 0x1000; return baseAddress + baseOrLimit * 0x1000;
} }
// Calculate offset of region using it's base // Calculate offset of region using its base
UINT32 calculateRegionOffset(const UINT16 base) UINT32 calculateRegionOffset(const UINT16 base)
{ {
return base * 0x1000; return base * 0x1000;
} }
//Calculate size of region using it's base and limit //Calculate size of region using its base and limit
UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit) UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit)
{ {
if (limit) if (limit)
@ -114,6 +114,14 @@ UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1)
case 0x20BB19: return UString("Micron MT25Q256"); case 0x20BB19: return UString("Micron MT25Q256");
case 0x20BB20: return UString("Micron MT25Q512"); case 0x20BB20: return UString("Micron MT25Q512");
// Intel
case 0x898911: return UString("Intel 25F160S33B8");
case 0x898912: return UString("Intel 25F320S33B8");
case 0x898913: return UString("Intel 25F640S33B8");
case 0x898915: return UString("Intel 25F160S33T8");
case 0x898916: return UString("Intel 25F320S33T8");
case 0x898917: return UString("Intel 25F640S33T8");
// Atmel // Atmel
case 0x1F4500: return UString("Atmel AT26DF081"); case 0x1F4500: return UString("Atmel AT26DF081");
case 0x1F4501: return UString("Atmel AT26DF081A"); case 0x1F4501: return UString("Atmel AT26DF081A");
@ -177,11 +185,15 @@ UString jedecIdToUString(UINT8 vendorId, UINT8 deviceId0, UINT8 deviceId1)
case 0x374016: return UString("Amic A25L032A"); case 0x374016: return UString("Amic A25L032A");
// PMC // PMC
case 0x7F9D13: return UString("PMC Pm25LV080B"); case 0x9DF713: return UString("PMC Pm25LV080B");
case 0x7F9D14: return UString("PMC Pm25LV016B"); case 0x9DF714: return UString("PMC Pm25LV016B");
case 0x7F9D44: return UString("PMC Pm25LQ080C"); case 0x9DF744: return UString("PMC Pm25LQ080C");
case 0x7F9D45: return UString("PMC Pm25LQ016C"); case 0x9DF745: return UString("PMC Pm25LQ016C");
case 0x7F9D46: return UString("PMC Pm25LQ032C"); case 0x9DF746: return UString("PMC Pm25LQ032C");
case 0x9DF77B: return UString("PMC Pm25LV512A");
case 0x9DF77C: return UString("PMC Pm25LV010A");
case 0x9DF77D: return UString("PMC Pm25LV020");
case 0x9DF77E: return UString("PMC Pm25LV040");
// ISSI // ISSI
case 0x9D6017: return UString("ISSI Ix25LP064"); case 0x9D6017: return UString("ISSI Ix25LP064");

View file

@ -34,6 +34,19 @@ typedef struct FLASH_DESCRIPTOR_HEADER_ {
// Maximum base value in descriptor map // Maximum base value in descriptor map
#define FLASH_DESCRIPTOR_MAX_BASE 0xE0 #define FLASH_DESCRIPTOR_MAX_BASE 0xE0
// Descriptor version was reserved in older firmware
#define FLASH_DESCRIPTOR_VERSION_INVALID 0xFFFFFFFF
// The only known version found in Coffee Lake
#define FLASH_DESCRIPTOR_VERSION_MAJOR 1
#define FLASH_DESCRIPTOR_VERSION_MINOR 0
// Descriptor version present in Coffee Lake and newer
typedef struct _FLASH_DESCRIPTOR_VERSION {
UINT32 Reserved : 14;
UINT32 Minor : 7;
UINT32 Major : 11;
} FLASH_DESCRIPTOR_VERSION;
// Descriptor map // Descriptor map
// Base fields are storing bits [11:4] of actual base addresses, all other bits are 0 // Base fields are storing bits [11:4] of actual base addresses, all other bits are 0
typedef struct FLASH_DESCRIPTOR_MAP_ { typedef struct FLASH_DESCRIPTOR_MAP_ {
@ -54,6 +67,8 @@ typedef struct FLASH_DESCRIPTOR_MAP_ {
UINT32 ProcStrapsBase : 8; UINT32 ProcStrapsBase : 8;
UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb) UINT32 NumberOfProcStraps : 8; // One-based number of UINT32s to read as processor straps, min=0, max=255 (1 Kb)
UINT32 : 16; UINT32 : 16;
// FLMAP 3
UINT32 DescriptorVersion; // Reserved prior to Coffee Lake
} FLASH_DESCRIPTOR_MAP; } FLASH_DESCRIPTOR_MAP;
// Component section // Component section

View file

@ -21,10 +21,6 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
if (!index.isValid()) if (!index.isValid())
return U_INVALID_PARAMETER; return U_INVALID_PARAMETER;
// Construct a name for extracted data
UString itemName = model->name(index);
UString itemText = model->text(index);
// Default name // Default name
name = uniqueItemName(index); name = uniqueItemName(index);
@ -77,10 +73,8 @@ USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data,
else if (mode == REPLACE_MODE_BODY) { else if (mode == REPLACE_MODE_BODY) {
return U_NOT_IMPLEMENTED; return U_NOT_IMPLEMENTED;
} }
else
return U_UNKNOWN_REPLACE_MODE;
return U_NOT_IMPLEMENTED; return U_UNKNOWN_REPLACE_MODE;
} }
USTATUS FfsOperations::remove(const UModelIndex & index) USTATUS FfsOperations::remove(const UModelIndex & index)

File diff suppressed because it is too large Load diff

View file

@ -66,7 +66,7 @@ public:
private: private:
TreeModel *model; TreeModel *model;
std::vector<std::pair<UString, UModelIndex> > messagesVector; std::vector<std::pair<UString, UModelIndex> > messagesVector;
void msg(const UString message, const UModelIndex index = UModelIndex()) { void msg(const UString & message, const UModelIndex & index = UModelIndex()) {
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}; };
@ -75,7 +75,7 @@ private:
UByteArray openedImage; UByteArray openedImage;
UModelIndex lastVtf; UModelIndex lastVtf;
UINT32 capsuleOffsetFixup; UINT32 imageBase;
UINT64 addressDiff; UINT64 addressDiff;
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable; std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
@ -93,6 +93,10 @@ private:
// First pass // First pass
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index); USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
USTATUS parseCapsule(const UByteArray & capsule, UModelIndex & index);
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseRawArea(const UModelIndex & index); USTATUS parseRawArea(const UModelIndex & index);
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseVolumeBody(const UModelIndex & index); USTATUS parseVolumeBody(const UModelIndex & index);
@ -101,7 +105,6 @@ private:
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
USTATUS parseSectionBody(const UModelIndex & index); USTATUS parseSectionBody(const UModelIndex & index);
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & root);
USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
@ -129,7 +132,7 @@ private:
USTATUS parseTeImageSectionBody(const UModelIndex & index); USTATUS parseTeImageSectionBody(const UModelIndex & index);
USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed); USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 localOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize); USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion); UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion); UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);

View file

@ -21,31 +21,31 @@ std::vector<UString> FfsReport::generate()
// Check model pointer // Check model pointer
if (!model) { if (!model) {
report.push_back(UString("ERROR: Invalid model pointer provided")); report.push_back(usprintf("%s: invalid model pointer provided", __FUNCTION__));
return report; return report;
} }
// Check root index to be valid // Check root index to be valid
UModelIndex root = model->index(0,0); UModelIndex root = model->index(0,0);
if (!root.isValid()) { if (!root.isValid()) {
report.push_back(UString("ERROR: Model root index is invalid")); report.push_back(usprintf("%s: model root index is invalid", __FUNCTION__));
return report; return report;
} }
// Generate report recursive // Generate report recursive
report.push_back(UString(" Type | Subtype | Size | CRC32 | Name ")); report.push_back(UString(" Type | Subtype | Offset | Size | CRC32 | Name "));
USTATUS result = generateRecursive(report, root); USTATUS result = generateRecursive(report, root);
if (result) { if (result) {
report.push_back(UString("ERROR: generateRecursive returned ") + errorCodeToUString(result)); report.push_back(usprintf("%s: generateRecursive returned ", __FUNCTION__) + errorCodeToUString(result));
} }
return report; return report;
} }
USTATUS FfsReport::generateRecursive(std::vector<UString> & report, UModelIndex index, UINT32 level) USTATUS FfsReport::generateRecursive(std::vector<UString> & report, const UModelIndex & index, const UINT32 level)
{ {
if (!index.isValid()) if (!index.isValid())
return U_SUCCESS; //Nothing to report for invalid index return U_SUCCESS; // Nothing to report for invalid index
// Calculate item CRC32 // Calculate item CRC32
UByteArray data = model->header(index) + model->body(index) + model->tail(index); UByteArray data = model->header(index) + model->body(index) + model->tail(index);
@ -53,18 +53,24 @@ USTATUS FfsReport::generateRecursive(std::vector<UString> & report, UModelIndex
// Information on current item // Information on current item
UString text = model->text(index); UString text = model->text(index);
UString offset = "| N/A ";
if ((!model->compressed(index)) || (index.parent().isValid() && !model->compressed(index.parent()))) {
offset = usprintf("| %08X ", model->offset(index));
}
report.push_back( report.push_back(
UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16) UString(" ") + itemTypeToUString(model->type(index)).leftJustified(16)
+ UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22) + UString("| ") + itemSubtypeToUString(model->type(index), model->subtype(index)).leftJustified(22)
+ offset
+ usprintf("| %08X | %08X | ", data.size(), crc) + usprintf("| %08X | %08X | ", data.size(), crc)
+ urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString("") : UString(" | ") + text) + urepeated('-', level) + UString(" ") + model->name(index) + (text.isEmpty() ? UString() : UString(" | ") + text)
); );
// Information on child items // Information on child items
for (int i = 0; i < model->rowCount(index); i++) { for (int i = 0; i < model->rowCount(index); i++) {
generateRecursive(report, index.child(i,0), level + 1); generateRecursive(report, index.child(i,0), level + 1);
} }
return U_SUCCESS; return U_SUCCESS;
} }

View file

@ -34,7 +34,7 @@ public:
private: private:
TreeModel* model; TreeModel* model;
USTATUS generateRecursive(std::vector<UString> & report, UModelIndex index, UINT32 level = 0); USTATUS generateRecursive(std::vector<UString> & report, const UModelIndex & index, const UINT32 level = 0);
}; };
#endif // FFSREPORT_H #endif // FFSREPORT_H

View file

@ -56,7 +56,7 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
} }
if (numEntries) if (numEntries)
*numEntries = gGuidToUStringMap.size(); *numEntries = (UINT32)gGuidToUStringMap.size();
} }
UString guidDatabaseLookup(const EFI_GUID & guid) UString guidDatabaseLookup(const EFI_GUID & guid)

View file

@ -12,6 +12,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/ */
// A workaround for compilers not supporting c++11 and c11
// for using PRIX64.
#define __STDC_FORMAT_MACROS
#include <inttypes.h> #include <inttypes.h>
#include <map> #include <map>
@ -102,7 +106,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
else { else {
// Nothing is parsed yet, but the file is not empty // Nothing is parsed yet, but the file is not empty
if (!offset) { if (!offset) {
msg(UString("parseNvarStore: file can't be parsed as NVAR variables store"), index); msg(usprintf("%s: file can't be parsed as NVAR variables store", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -225,7 +229,8 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
isInvalidLink = true; isInvalidLink = true;
UModelIndex nvarIndex; UModelIndex nvarIndex;
// Search prevously added entries for a link to this variable // Search prevously added entries for a link to this variable
for (int i = 0; i < model->rowCount(index); i++) { // WARNING: O(n^2), may be very slow
for (int i = model->rowCount(index) - 1; i >= 0; i--) {
nvarIndex = index.child(i, 0); nvarIndex = index.child(i, 0);
if (model->hasEmptyParsingData(nvarIndex) == false) { if (model->hasEmptyParsingData(nvarIndex) == false) {
UByteArray nvarData = model->parsingData(nvarIndex); UByteArray nvarData = model->parsingData(nvarIndex);
@ -352,10 +357,10 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
model->setParsingData(varIndex, UByteArray((const char*)&pdata, sizeof(pdata))); model->setParsingData(varIndex, UByteArray((const char*)&pdata, sizeof(pdata)));
// Show messages // Show messages
if (msgUnknownExtDataFormat) msg(UString("parseNvarStore: unknown extended data format"), varIndex); if (msgUnknownExtDataFormat) msg(usprintf("%s: unknown extended data format", __FUNCTION__), varIndex);
if (msgExtHeaderTooLong) msg(usprintf("parseNvarStore: extended header size (%Xh) is greater than body size (%Xh)", if (msgExtHeaderTooLong) msg(usprintf("%s: extended header size (%Xh) is greater than body size (%Xh)", __FUNCTION__,
extendedHeaderSize, body.size()), varIndex); extendedHeaderSize, body.size()), varIndex);
if (msgExtDataTooShort) msg(usprintf("parseNvarStore: extended header size (%Xh) is too small for timestamp and hash", if (msgExtDataTooShort) msg(usprintf("%s: extended header size (%Xh) is too small for timestamp and hash", __FUNCTION__,
tail.size()), varIndex); tail.size()), varIndex);
// Try parsing the entry data as NVAR storage if it begins with NVAR signature // Try parsing the entry data as NVAR storage if it begins with NVAR signature
@ -433,7 +438,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
UINT32 storeSize = 0; UINT32 storeSize = 0;
result = getStoreSize(data, storeOffset, storeSize); result = getStoreSize(data, storeOffset, storeSize);
if (result) { if (result) {
msg(UString("parseNvramVolumeBody: getStoreSize failed with error ") + errorCodeToUString(result), index); msg(usprintf("%s: getStoreSize failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
return result; return result;
} }
@ -448,7 +453,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
// Add tree item // Add tree item
UModelIndex paddingIndex = model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); UModelIndex paddingIndex = model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
msg(UString("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex); msg(usprintf("%s: one of stores inside overlaps the end of data", __FUNCTION__), paddingIndex);
// Update variables // Update variables
prevStoreOffset = storeOffset; prevStoreOffset = storeOffset;
@ -461,7 +466,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
UByteArray store = data.mid(storeOffset, storeSize); UByteArray store = data.mid(storeOffset, storeSize);
result = parseStoreHeader(store, localOffset + storeOffset, index, storeIndex); result = parseStoreHeader(store, localOffset + storeOffset, index, storeIndex);
if (result) if (result)
msg(UString("parseNvramVolumeBody: store header parsing failed with error ") + errorCodeToUString(result), index); msg(usprintf("%s: store header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
// Go to next store // Go to next store
prevStoreOffset = storeOffset; prevStoreOffset = storeOffset;
@ -483,7 +488,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index)
else { else {
// Nothing is parsed yet, but the file is not empty // Nothing is parsed yet, but the file is not empty
if (!storeOffset) { if (!storeOffset) {
msg(UString("parseNvramVolumeBody: can't be parsed as NVRAM volume"), index); msg(usprintf("%s: can't be parsed as NVRAM volume", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -521,11 +526,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks
const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos; const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos;
if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) {
msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", localOffset + offset, vssHeader->Format), index); msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index);
continue; continue;
} }
if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) {
msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, vssHeader->Size), index); msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, vssHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -538,11 +543,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
const VSS2_VARIABLE_STORE_HEADER* vssHeader = (const VSS2_VARIABLE_STORE_HEADER*)currentPos; const VSS2_VARIABLE_STORE_HEADER* vssHeader = (const VSS2_VARIABLE_STORE_HEADER*)currentPos;
if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) {
msg(usprintf("findNextStore: VSS2 store candidate at offset %Xh skipped, has invalid format %02Xh", localOffset + offset, vssHeader->Format), index); msg(usprintf("%s: VSS2 store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index);
continue; continue;
} }
if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) {
msg(usprintf("findNextStore: VSS2 store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, vssHeader->Size), index); msg(usprintf("%s: VSS2 store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, vssHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -551,7 +556,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found
const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos; const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos;
if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) { if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) {
msg(usprintf("findNextStore: FDC store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fdcHeader->Size), index); msg(usprintf("%s: FDC store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fdcHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -560,7 +565,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos; const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos;
if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) { if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) {
msg(usprintf("findNextStore: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fsysHeader->Size), index); msg(usprintf("%s: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fsysHeader->Size), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -572,11 +577,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1); const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1);
if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) { if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) {
msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", localOffset + offset - 4, evsaHeader->Header.Type), index); msg(usprintf("%s: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", __FUNCTION__, localOffset + offset - 4, evsaHeader->Header.Type), index);
continue; continue;
} }
if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) { if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) {
msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, evsaHeader->StoreSize), index); msg(usprintf("%s: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, evsaHeader->StoreSize), index);
continue; continue;
} }
// All checks passed, store found // All checks passed, store found
@ -592,14 +597,14 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray &
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos; const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos;
if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize
if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) { if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) {
msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftwHeader->WriteQueueSize), index); msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", __FUNCTION__, localOffset + offset, ftwHeader->WriteQueueSize), index);
continue; continue;
} }
} }
else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos; const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos;
if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) { if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) {
msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftw64Header->WriteQueueSize), index); msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", __FUNCTION__, localOffset + offset, ftw64Header->WriteQueueSize), index);
continue; continue;
} }
} }
@ -750,7 +755,7 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) { if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) {
msg(UString("parseVssStoreHeader: volume body is too small even for VSS store header"), parent); msg(usprintf("%s: volume body is too small even for VSS store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -765,7 +770,7 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < storeSize) { if (dataSize < storeSize) {
msg(usprintf("parseVssStoreHeader: VSS store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: VSS store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
storeSize, storeSize, storeSize, storeSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -799,7 +804,7 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(VSS2_VARIABLE_STORE_HEADER)) { if (dataSize < sizeof(VSS2_VARIABLE_STORE_HEADER)) {
msg(UString("parseVss2StoreHeader: volume body is too small even for VSS2 store header"), parent); msg(usprintf("%s: volume body is too small even for VSS2 store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -814,7 +819,7 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < storeSize) { if (dataSize < storeSize) {
msg(usprintf("parseVssStoreHeader: VSS2 store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: VSS2 store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
storeSize, storeSize, storeSize, storeSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -847,13 +852,13 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) { if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) {
msg(UString("parseFtwStoreHeader: volume body is too small even for FTW store header"), parent); msg(usprintf("%s: volume body is too small even for FTW store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
// Obtain required information from parent volume // Obtain required information from parent volume
UINT8 emptyByte = 0xFF; UINT8 emptyByte = 0xFF;
UModelIndex parentVolumeIndex = model->findParentOfType(index, Types::Volume); UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume);
if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) { if (parentVolumeIndex.isValid() && model->hasEmptyParsingData(parentVolumeIndex) == false) {
UByteArray data = model->parsingData(parentVolumeIndex); UByteArray data = model->parsingData(parentVolumeIndex);
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData(); const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
@ -876,7 +881,7 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
has32bitHeader = false; has32bitHeader = false;
} }
if (dataSize < ftwBlockSize) { if (dataSize < ftwBlockSize) {
msg(usprintf("parseFtwStoreHeader: FTW store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: FTW store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
ftwBlockSize, ftwBlockSize, ftwBlockSize, ftwBlockSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -917,7 +922,7 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(FDC_VOLUME_HEADER)) { if (dataSize < sizeof(FDC_VOLUME_HEADER)) {
msg(UString("parseFdcStoreHeader: volume body is too small even for FDC store header"), parent); msg(usprintf("%s: volume body is too small even for FDC store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -926,24 +931,15 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < fdcStoreHeader->Size) { if (dataSize < fdcStoreHeader->Size) {
msg(usprintf("parseFdcStoreHeader: FDC store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: FDC store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
fdcStoreHeader->Size, fdcStoreHeader->Size,
dataSize, dataSize), parent);
return U_SUCCESS;
}
// Check header size
UINT32 headerSize = sizeof(FDC_VOLUME_HEADER);
if (dataSize < headerSize) {
msg(usprintf("parseFdcStoreHeader: FDC store header size %Xh (%u) is greater than volume body size %Xh (%u)",
fdcStoreHeader->Size, fdcStoreHeader->Size, fdcStoreHeader->Size, fdcStoreHeader->Size,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
} }
// Construct header and body // Construct header and body
UByteArray header = store.left(headerSize); UByteArray header = store.left(sizeof(FDC_VOLUME_HEADER));
UByteArray body = store.mid(headerSize, fdcStoreHeader->Size - headerSize); UByteArray body = store.mid(sizeof(FDC_VOLUME_HEADER), fdcStoreHeader->Size - sizeof(FDC_VOLUME_HEADER));
// Add info // Add info
UString name("FDC store"); UString name("FDC store");
@ -964,7 +960,7 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) { if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) {
msg(UString("parseFsysStoreHeader: volume body is too small even for Fsys store header"), parent); msg(usprintf("%s: volume body is too small even for Fsys store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -973,7 +969,7 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < fsysStoreHeader->Size) { if (dataSize < fsysStoreHeader->Size) {
msg(usprintf("parseFsysStoreHeader: Fsys store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: Fsys store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
fsysStoreHeader->Size, fsysStoreHeader->Size, fsysStoreHeader->Size, fsysStoreHeader->Size,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1011,7 +1007,7 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
// Check dataSize // Check dataSize
if (dataSize < sizeof(EVSA_STORE_ENTRY)) { if (dataSize < sizeof(EVSA_STORE_ENTRY)) {
msg(UString("parseEvsaStoreHeader: volume body is too small even for EVSA store header"), parent); msg(usprintf("%s: volume body is too small even for EVSA store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1020,7 +1016,7 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < evsaStoreHeader->StoreSize) { if (dataSize < evsaStoreHeader->StoreSize) {
msg(usprintf("parseEvsaStoreHeader: EVSA store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: EVSA store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1056,7 +1052,7 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
// Check data size // Check data size
if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) { if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) {
msg(UString("parseFlashMapStoreHeader: volume body is too small even for FlashMap block header"), parent); msg(usprintf("%s: volume body is too small even for FlashMap block header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1066,7 +1062,7 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
// Check store size // Check store size
UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY); UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY);
if (dataSize < flashMapSize) { if (dataSize < flashMapSize) {
msg(usprintf("parseFlashMapStoreHeader: FlashMap block size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: FlashMap block size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
flashMapSize, flashMapSize, flashMapSize, flashMapSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1096,13 +1092,13 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32
// Check store size // Check store size
if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) { if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) {
msg(UString("parseCmdbStoreHeader: volume body is too small even for CMDB store header"), parent); msg(usprintf("%s: volume body is too small even for CMDB store header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE; UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE;
if (dataSize < cmdbSize) { if (dataSize < cmdbSize) {
msg(usprintf("parseCmdbStoreHeader: CMDB store size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: CMDB store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
cmdbSize, cmdbSize, cmdbSize, cmdbSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1134,7 +1130,7 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
// Check data size // Check data size
if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) { if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) {
msg(UString("parseSlicPubkeyHeader: volume body is too small even for SLIC pubkey header"), parent); msg(usprintf("%s: volume body is too small even for SLIC pubkey header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1143,7 +1139,7 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
// Check store size // Check store size
if (dataSize < pubkeyHeader->Size) { if (dataSize < pubkeyHeader->Size) {
msg(usprintf("parseSlicPubkeyHeader: SLIC pubkey size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: SLIC pubkey size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
pubkeyHeader->Size, pubkeyHeader->Size, pubkeyHeader->Size, pubkeyHeader->Size,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1176,7 +1172,7 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
// Check data size // Check data size
if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) { if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) {
msg(UString("parseSlicMarkerHeader: volume body is too small even for SLIC marker header"), parent); msg(usprintf("%s: volume body is too small even for SLIC marker header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1185,7 +1181,7 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
// Check store size // Check store size
if (dataSize < markerHeader->Size) { if (dataSize < markerHeader->Size) {
msg(usprintf("parseSlicMarkerHeader: SLIC marker size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: SLIC marker size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
markerHeader->Size, markerHeader->Size, markerHeader->Size, markerHeader->Size,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1218,7 +1214,7 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
// Check data size // Check data size
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) { if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
msg(UString("parseIntelMicrocodeHeader: volume body is too small even for Intel microcode header"), parent); msg(usprintf("%s: volume body is too small even for Intel microcode header", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1227,7 +1223,7 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
// Check store size // Check store size
if (dataSize < ucodeHeader->TotalSize) { if (dataSize < ucodeHeader->TotalSize) {
msg(usprintf("parseIntelMicrocodeHeader: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", msg(usprintf("%s: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
ucodeHeader->TotalSize, ucodeHeader->TotalSize, ucodeHeader->TotalSize, ucodeHeader->TotalSize,
dataSize, dataSize), parent); dataSize, dataSize), parent);
return U_SUCCESS; return U_SUCCESS;
@ -1267,7 +1263,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
const UINT32* signature = (const UINT32*)store.constData(); const UINT32* signature = (const UINT32*)store.constData();
// Check store size // Check store size
if (dataSize < sizeof(UINT32)) { if (dataSize < sizeof(UINT32)) {
msg(UString("parseStoreHeader: volume body is too small even for store signature"), parent); msg(usprintf("%s: volume body is too small even for a store signature", __FUNCTION__), parent);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1288,7 +1284,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE)
return parseFsysStoreHeader(store, localOffset, parent, index); return parseFsysStoreHeader(store, localOffset, parent, index);
// EVSA store // EVSA store
else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) else if (dataSize >= 2 * sizeof(UINT32) && *(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE)
return parseEvsaStoreHeader(store, localOffset, parent, index); return parseEvsaStoreHeader(store, localOffset, parent, index);
// Phoenix SCT flash map // Phoenix SCT flash map
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1)
@ -1297,10 +1293,10 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE)
return parseCmdbStoreHeader(store, localOffset, parent, index); return parseCmdbStoreHeader(store, localOffset, parent, index);
// SLIC pubkey // SLIC pubkey
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) else if (dataSize >= 5 * sizeof(UINT32) && *(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC)
return parseSlicPubkeyHeader(store, localOffset, parent, index); return parseSlicPubkeyHeader(store, localOffset, parent, index);
// SLIC marker // SLIC marker
else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) else if (dataSize >= 34 && *(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG)
return parseSlicMarkerHeader(store, localOffset, parent, index); return parseSlicMarkerHeader(store, localOffset, parent, index);
// Intel microcode // Intel microcode
// Must be checked after SLIC marker because of the same *signature values // Must be checked after SLIC marker because of the same *signature values
@ -1327,20 +1323,20 @@ USTATUS NvramParser::parseFdcStoreBody(const UModelIndex & index)
UModelIndex volumeIndex; UModelIndex volumeIndex;
USTATUS status = ffsParser->parseVolumeHeader(data, localOffset, index, volumeIndex); USTATUS status = ffsParser->parseVolumeHeader(data, localOffset, index, volumeIndex);
if (status || !volumeIndex.isValid()) { if (status || !volumeIndex.isValid()) {
msg(UString("parseFdcStoreBody: store can't be parsed as FDC store"), index); msg(usprintf("%s: store can't be parsed as FDC store", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
// Determine if it's a VSS or VSS2 store inside // Determine if it's a VSS or VSS2 store inside
UByteArray store = model->body(volumeIndex); UByteArray store = model->body(volumeIndex);
if (store.size() >= sizeof(UINT32) && *(const UINT32*)store.constData() == NVRAM_VSS_STORE_SIGNATURE) { if ((UINT32)store.size() >= sizeof(UINT32) && *(const UINT32*)store.constData() == NVRAM_VSS_STORE_SIGNATURE) {
UModelIndex vssIndex; UModelIndex vssIndex;
status = parseVssStoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vssIndex); status = parseVssStoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vssIndex);
if (status) if (status)
return status; return status;
return parseVssStoreBody(vssIndex, 0); return parseVssStoreBody(vssIndex, 0);
} }
else if (store.size() >= sizeof(EFI_GUID) && store.left(sizeof(EFI_GUID)) == NVRAM_FDC_STORE_GUID) { else if ((UINT32)store.size() >= sizeof(EFI_GUID) && store.left(sizeof(EFI_GUID)) == NVRAM_FDC_STORE_GUID) {
UModelIndex vss2Index; UModelIndex vss2Index;
status = parseVss2StoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vss2Index); status = parseVss2StoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vss2Index);
if (status) if (status)
@ -1348,7 +1344,7 @@ USTATUS NvramParser::parseFdcStoreBody(const UModelIndex & index)
return parseVssStoreBody(vss2Index, 0); return parseVssStoreBody(vss2Index, 0);
} }
else { else {
msg(UString("parseFdcStoreBody: internal volume can't be parsed as VSS/VSS2 store"), index); msg(usprintf("%s: internal volume can't be parsed as VSS/VSS2 store", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1378,7 +1374,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
// Check that the is enough space for variable header // Check that the is enough space for variable header
const UINT32 dataSize = (UINT32)data.size(); const UINT32 dataSize = (UINT32)data.size();
if (dataSize < sizeof(VSS_VARIABLE_HEADER)) { if (dataSize < sizeof(VSS_VARIABLE_HEADER)) {
msg(UString("parseVssStoreBody: store body is too small even for VSS variable header"), index); msg(usprintf("%s: store body is too small even for VSS variable header", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1386,7 +1382,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
// Parse all variables // Parse all variables
while (1) { while (1) {
bool isInvalid = false; bool isInvalid = true;
bool isAuthenticated = false; bool isAuthenticated = false;
bool isAppleCrc32 = false; bool isAppleCrc32 = false;
bool isIntelSpecial = false; bool isIntelSpecial = false;
@ -1394,13 +1390,13 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
UINT32 storedCrc32 = 0; UINT32 storedCrc32 = 0;
UINT32 calculatedCrc32 = 0; UINT32 calculatedCrc32 = 0;
UINT64 monotonicCounter = 0; UINT64 monotonicCounter = 0;
EFI_TIME timestamp = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; EFI_TIME timestamp = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
UINT32 pubKeyIndex = 0; UINT32 pubKeyIndex = 0;
UINT8 subtype = 0; UINT8 subtype = 0;
UString name; UString name;
UString text; UString text;
EFI_GUID* variableGuid; EFI_GUID* variableGuid = NULL;
CHAR16* variableName = (CHAR16*)L""; CHAR16* variableName = (CHAR16*)L"";
UByteArray header; UByteArray header;
UByteArray body; UByteArray body;
@ -1460,7 +1456,8 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
} }
// Intel special variable // Intel special variable
else if (variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_VALID || variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_INVALID) { else if (variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_VALID
|| variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_INVALID) {
isIntelSpecial = true; isIntelSpecial = true;
const VSS_INTEL_VARIABLE_HEADER* intelVariableHeader = (const VSS_INTEL_VARIABLE_HEADER*)variableHeader; const VSS_INTEL_VARIABLE_HEADER* intelVariableHeader = (const VSS_INTEL_VARIABLE_HEADER*)variableHeader;
variableSize = intelVariableHeader->TotalSize; variableSize = intelVariableHeader->TotalSize;
@ -1478,7 +1475,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
} }
// Normal VSS variable // Normal VSS variable
if (!isAuthenticated && !isAppleCrc32 && !isIntelSpecial) { else {
variableSize = sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize + variableHeader->DataSize; variableSize = sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize + variableHeader->DataSize;
variableGuid = (EFI_GUID*)&variableHeader->VendorGuid; variableGuid = (EFI_GUID*)&variableHeader->VendorGuid;
variableName = (CHAR16*)(variableHeader + 1); variableName = (CHAR16*)(variableHeader + 1);
@ -1488,8 +1485,10 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
} }
// Check variable state // Check variable state
if (variableHeader->State != NVRAM_VSS_INTEL_VARIABLE_VALID && variableHeader->State != NVRAM_VSS_VARIABLE_ADDED && variableHeader->State != NVRAM_VSS_VARIABLE_HEADER_VALID) { if (variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_VALID
isInvalid = true; || variableHeader->State == NVRAM_VSS_VARIABLE_ADDED
|| variableHeader->State == NVRAM_VSS_VARIABLE_HEADER_VALID) {
isInvalid = false;
} }
// Check variable size // Check variable size
@ -1512,7 +1511,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
else { // Padding else { // Padding
// Nothing is parsed yet, but the store is not empty // Nothing is parsed yet, but the store is not empty
if (!offset) { if (!offset) {
msg(UString("parseVssStoreBody: store can't be parsed as VSS store"), index); msg(usprintf("%s: store can't be parsed as VSS store", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1526,7 +1525,8 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
UString info; UString info;
// Rename invalid variables // Rename invalid variables
if (isInvalid) { if (isInvalid || !variableGuid) {
isInvalid = true;
name = UString("Invalid"); name = UString("Invalid");
} }
else { // Add GUID and text for valid variables else { // Add GUID and text for valid variables
@ -1560,8 +1560,9 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
else if (isIntelSpecial) { else if (isIntelSpecial) {
subtype = Subtypes::IntelVssEntry; subtype = Subtypes::IntelVssEntry;
} }
else else {
subtype = Subtypes::StandardVssEntry; subtype = Subtypes::StandardVssEntry;
}
// Add tree item // Add tree item
model->addItem(localOffset + offset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Movable, index); model->addItem(localOffset + offset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Movable, index);
@ -1591,12 +1592,12 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Check that the is enough space for variable header // Check that the is enough space for variable header
const UINT32 dataSize = (UINT32)data.size(); const UINT32 storeDataSize = (UINT32)data.size();
UINT32 offset = 0; UINT32 offset = 0;
// Parse all variables // Parse all variables
while (1) { while (1) {
UINT32 unparsedSize = dataSize - offset; UINT32 unparsedSize = storeDataSize - offset;
UINT32 variableSize = 0; UINT32 variableSize = 0;
// Get nameSize and name of the variable // Get nameSize and name of the variable
@ -1647,7 +1648,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Show message // Show message
msg(UString("parseFsysStoreBody: next variable appears too big, added as padding"), index); msg(usprintf("%s: next variable appears too big, added as padding", __FUNCTION__), index);
return U_SUCCESS; return U_SUCCESS;
} }
@ -1694,14 +1695,14 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
const UByteArray data = model->body(index); const UByteArray data = model->body(index);
// Check that the is enough space for entry header // Check that the is enough space for entry header
const UINT32 dataSize = (UINT32)data.size(); const UINT32 storeDataSize = (UINT32)data.size();
UINT32 offset = 0; UINT32 offset = 0;
std::map<UINT16, EFI_GUID> guidMap; std::map<UINT16, EFI_GUID> guidMap;
std::map<UINT16, UString> nameMap; std::map<UINT16, UString> nameMap;
// Parse all entries // Parse all entries
UINT32 unparsedSize = dataSize; UINT32 unparsedSize = storeDataSize;
while (unparsedSize) { while (unparsedSize) {
UINT32 variableSize = 0; UINT32 variableSize = 0;
UString name; UString name;
@ -1716,8 +1717,8 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
// Check entry size // Check entry size
variableSize = sizeof(EVSA_ENTRY_HEADER); variableSize = sizeof(EVSA_ENTRY_HEADER);
if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) { if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) {
UByteArray body = data.mid(offset); body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
if (body.count(emptyByte) == body.size()) { // Free space if (body.count(emptyByte) == body.size()) { // Free space
// Add free space tree item // Add free space tree item
@ -1728,7 +1729,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Show message // Show message
msg(UString("parseEvsaStoreBody: variable parsing failed, the rest of unparsed store added as padding"), itemIndex); msg(usprintf("%s: variable parsing failed, the rest of unparsed store added as padding", __FUNCTION__), itemIndex);
} }
break; break;
} }
@ -1808,8 +1809,8 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
} }
// Unknown entry or free space // Unknown entry or free space
else { else {
UByteArray body = data.mid(offset); body = data.mid(offset);
UString info = usprintf("Full size: %Xh (%u)", body.size(), body.size()); info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
if (body.count(emptyByte) == body.size()) { // Free space if (body.count(emptyByte) == body.size()) { // Free space
// Add free space tree item // Add free space tree item
@ -1820,7 +1821,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Show message // Show message
msg(usprintf("parseEvsaStoreBody: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding", entryHeader->Type, offset), itemIndex); msg(usprintf("%s: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding", __FUNCTION__, entryHeader->Type, offset), itemIndex);
} }
break; break;
} }
@ -1830,7 +1831,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
// Move to next variable // Move to next variable
offset += variableSize; offset += variableSize;
unparsedSize = dataSize - offset; unparsedSize = storeDataSize - offset;
} }
// Reparse all data variables to detect invalid ones and assign name and test to valid ones // Reparse all data variables to detect invalid ones and assign name and test to valid ones
@ -1850,17 +1851,17 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index)
if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found
model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid")); model->setName(current, UString("Invalid"));
msg(UString("parseEvsaStoreBody: data variable with invalid GuidId and invalid VarId"), current); msg(usprintf("%s: data variable with invalid GuidId and invalid VarId", __FUNCTION__), current);
} }
else if (guid.isEmpty()) { // Guid not found else if (guid.isEmpty()) { // Guid not found
model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid")); model->setName(current, UString("Invalid"));
msg(UString("parseEvsaStoreBody: data variable with invalid GuidId"), current); msg(usprintf("%s: data variable with invalid GuidId", __FUNCTION__), current);
} }
else if (name.isEmpty()) { // Name not found else if (name.isEmpty()) { // Name not found
model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid")); model->setName(current, UString("Invalid"));
msg(UString("parseEvsaStoreBody: data variable with invalid VarId"), current); msg(usprintf("%s: data variable with invalid VarId", __FUNCTION__), current);
} }
else { // Variable is OK, rename it else { // Variable is OK, rename it
if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) {
@ -1909,7 +1910,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index)
// Show message // Show message
if (unparsedSize < entryHeader->Size) if (unparsedSize < entryHeader->Size)
msg(UString("parseFlashMapBody: next entry appears too big, added as padding"), index); msg(usprintf("%s: next entry appears too big, added as padding", __FUNCTION__), index);
break; break;
} }

View file

@ -44,7 +44,7 @@ private:
TreeModel *model; TreeModel *model;
FfsParser *ffsParser; FfsParser *ffsParser;
std::vector<std::pair<UString, UModelIndex> > messagesVector; std::vector<std::pair<UString, UModelIndex> > messagesVector;
void msg(const UString message, const UModelIndex index = UModelIndex()) { void msg(const UString & message, const UModelIndex & index = UModelIndex()) {
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index)); messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}; };

View file

@ -20,16 +20,16 @@ routines without the need of backward traversal
#include "basetypes.h" #include "basetypes.h"
typedef struct VOLUME_PARSING_DATA_ { typedef struct VOLUME_PARSING_DATA_ {
UINT8 ffsVersion;
UINT8 emptyByte;
EFI_GUID extendedHeaderGuid; EFI_GUID extendedHeaderGuid;
UINT32 alignment; UINT32 alignment;
UINT32 usedSpace;
BOOLEAN hasValidUsedSpace;
UINT8 ffsVersion;
UINT8 emptyByte;
UINT8 revision; UINT8 revision;
BOOLEAN hasExtendedHeader; BOOLEAN hasExtendedHeader;
BOOLEAN hasAppleCrc32; BOOLEAN hasAppleCrc32;
BOOLEAN isWeakAligned; BOOLEAN isWeakAligned;
BOOLEAN hasValidUsedSpace;
UINT32 usedSpace;
} VOLUME_PARSING_DATA; } VOLUME_PARSING_DATA;
typedef struct FILE_PARSING_DATA_ { typedef struct FILE_PARSING_DATA_ {

View file

@ -586,8 +586,8 @@ typedef struct {
} EFI_IMAGE_THUNK_DATA; } EFI_IMAGE_THUNK_DATA;
#define EFI_IMAGE_ORDINAL_FLAG 0x80000000 // Flag for PE32. #define EFI_IMAGE_ORDINAL_FLAG 0x80000000 // Flag for PE32.
#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) #define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) (((Ordinal) & EFI_IMAGE_ORDINAL_FLAG) != 0)
#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) #define EFI_IMAGE_ORDINAL(Ordinal) ((Ordinal) & 0xffff)
// //
// Import Directory Table // Import Directory Table

View file

@ -20,9 +20,10 @@ TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
const bool fixed, const bool compressed, const bool fixed, const bool compressed,
TreeItem *parent) : TreeItem *parent) :
itemOffset(offset), itemOffset(offset),
itemAction(Actions::NoAction), itemAction(Actions::NoAction),
itemType(type), itemType(type),
itemSubtype(subtype), itemSubtype(subtype),
itemMarking(0),
itemName(name), itemName(name),
itemText(text), itemText(text),
itemInfo(info), itemInfo(info),
@ -31,7 +32,6 @@ TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
itemTail(tail), itemTail(tail),
itemFixed(fixed), itemFixed(fixed),
itemCompressed(compressed), itemCompressed(compressed),
itemMarking(0),
parentItem(parent) parentItem(parent)
{ {
} }

View file

@ -40,7 +40,7 @@ not recommended that bformat be used at all. */
#define START_VSNBUFF (256) #define START_VSNBUFF (256)
#else #else
#if defined (__GNUC__) && !defined (__PPC__) #if defined (__GNUC__) && !defined (__PPC__) && !defined(__WIN32__)
/* Something is making gcc complain about this prototype not being here, so /* Something is making gcc complain about this prototype not being here, so
I've just gone ahead and put it in. */ I've just gone ahead and put it in. */
extern "C" { extern "C" {

View file

@ -34,6 +34,7 @@ UString uniqueItemName(const UModelIndex & index)
UString itemText = model->text(index); UString itemText = model->text(index);
// Default name // Default name
UString name = itemName; UString name = itemName;
switch (model->type(index)) { switch (model->type(index)) {
case Types::NvarEntry: case Types::NvarEntry:
@ -49,17 +50,26 @@ UString uniqueItemName(const UModelIndex & index)
UModelIndex fileIndex = model->findParentOfType(index, Types::File); UModelIndex fileIndex = model->findParentOfType(index, Types::File);
UString fileText = model->text(fileIndex); UString fileText = model->text(fileIndex);
name = fileText.isEmpty() ? model->name(fileIndex) : model->name(fileIndex) + '_' + fileText; name = fileText.isEmpty() ? model->name(fileIndex) : model->name(fileIndex) + '_' + fileText;
} break;
// Special case of GUIDed sections
if (model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
name = model->name(index) +'_' + name;
}
} break;
} }
// Populate subtypeString
UString subtypeString = itemSubtypeToUString(model->type(index), model->subtype(index)); UString subtypeString = itemSubtypeToUString(model->type(index), model->subtype(index));
// Create final name
name = itemTypeToUString(model->type(index)) name = itemTypeToUString(model->type(index))
+ (subtypeString.length() ? ('_' + subtypeString) : UString()) + (subtypeString.length() ? ('_' + subtypeString) : UString())
+ '_' + name; + '_' + name;
// Replace some symbols with underscopes for better readability
name.findreplace(' ', '_'); name.findreplace(' ', '_');
name.findreplace('/', '_'); name.findreplace('/', '_');
name.findreplace('-', '_'); name.findreplace('\\', '_');
return name; return name;
} }
@ -176,12 +186,12 @@ UINT32 crc32(UINT32 initial, const UINT8* buffer, const UINT32 length)
USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData) USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressedData, UByteArray & efiDecompressedData)
{ {
const UINT8* data; const UINT8* data;
UINT32 dataSize; UINT32 dataSize;
UINT8* decompressed; UINT8* decompressed;
UINT8* efiDecompressed; UINT8* efiDecompressed;
UINT32 decompressedSize = 0; UINT32 decompressedSize = 0;
UINT8* scratch; UINT8* scratch;
UINT32 scratchSize = 0; UINT32 scratchSize = 0;
const EFI_TIANO_HEADER* header; const EFI_TIANO_HEADER* header;
switch (compressionType) switch (compressionType)
@ -225,18 +235,25 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
// Try EFI 1.1 // Try EFI 1.1
USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize); USTATUS EfiResult = EfiDecompress(data, dataSize, efiDecompressed, decompressedSize, scratch, scratchSize);
if (decompressedSize > INT32_MAX) {
free(decompressed);
free(efiDecompressed);
free(scratch);
return U_STANDARD_DECOMPRESSION_FAILED;
}
if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK if (EfiResult == U_SUCCESS && TianoResult == U_SUCCESS) { // Both decompressions are OK
algorithm = COMPRESSION_ALGORITHM_UNDECIDED; algorithm = COMPRESSION_ALGORITHM_UNDECIDED;
decompressedData = UByteArray((const char*)decompressed, decompressedSize); decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
efiDecompressedData = UByteArray((const char*)efiDecompressed, decompressedSize); efiDecompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize);
} }
else if (TianoResult == U_SUCCESS) { // Only Tiano is OK else if (TianoResult == U_SUCCESS) { // Only Tiano is OK
algorithm = COMPRESSION_ALGORITHM_TIANO; algorithm = COMPRESSION_ALGORITHM_TIANO;
decompressedData = UByteArray((const char*)decompressed, decompressedSize); decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
} }
else if (EfiResult == U_SUCCESS) { // Only EFI 1.1 is OK else if (EfiResult == U_SUCCESS) { // Only EFI 1.1 is OK
algorithm = COMPRESSION_ALGORITHM_EFI11; algorithm = COMPRESSION_ALGORITHM_EFI11;
decompressedData = UByteArray((const char*)efiDecompressed, decompressedSize); decompressedData = UByteArray((const char*)efiDecompressed, (int)decompressedSize);
} }
else { // Both decompressions failed else { // Both decompressions failed
result = U_STANDARD_DECOMPRESSION_FAILED; result = U_STANDARD_DECOMPRESSION_FAILED;
@ -283,13 +300,21 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
return U_CUSTOMIZED_DECOMPRESSION_FAILED; return U_CUSTOMIZED_DECOMPRESSION_FAILED;
} }
else { else {
if (decompressedSize > INT32_MAX) {
free(decompressed);
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
algorithm = COMPRESSION_ALGORITHM_IMLZMA; algorithm = COMPRESSION_ALGORITHM_IMLZMA;
decompressedData = UByteArray((const char*)decompressed, decompressedSize); decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
} }
} }
else { else {
if (decompressedSize > INT32_MAX) {
free(decompressed);
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
algorithm = COMPRESSION_ALGORITHM_LZMA; algorithm = COMPRESSION_ALGORITHM_LZMA;
decompressedData = UByteArray((const char*)decompressed, decompressedSize); decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
} }
free(decompressed); free(decompressed);
@ -320,7 +345,7 @@ UINT8 calculateChecksum8(const UINT8* buffer, UINT32 bufferSize)
if (!buffer) if (!buffer)
return 0; return 0;
return (UINT8)0x100 - calculateSum8(buffer, bufferSize); return (UINT8)(0x100U - calculateSum8(buffer, bufferSize));
} }
// 16bit checksum calculation routine // 16bit checksum calculation routine
@ -341,6 +366,7 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize)
return (UINT16)(0x10000 - counter); return (UINT16)(0x10000 - counter);
} }
// Get padding type for a given padding
UINT8 getPaddingType(const UByteArray & padding) UINT8 getPaddingType(const UByteArray & padding)
{ {
if (padding.count('\x00') == padding.size()) if (padding.count('\x00') == padding.size())

123
unixbuild.sh Executable file
View file

@ -0,0 +1,123 @@
#!/bin/bash
UTARGET=$(uname)
BINSUFFIX=""
if [ "$UTARGET" = "Darwin" ]; then
export UPLATFORM="mac"
elif [ "$UTARGET" = "Linux" ]; then
export UPLATFORM="linux_$(uname -m)"
elif [ "${UTARGET/MINGW32/}" != "$UTARGET" ]; then
export UPLATFORM="win32"
export BINSUFFIX=".exe"
else
# Fallback to something...
export UPLATFORM="$UTARGET"
fi
if [ "$UPLATFORM" = "mac" ]; then
if [ ! -d /opt/qt56sm ]; then
curl -L -o /tmp/qt-5.6.3-static-mac.zip https://github.com/distdb/qtbuilds/blob/master/qt-5.6.3-static-mac.zip?raw=true || exit 1
qtsum=$(shasum -a 256 /tmp/qt-5.6.3-static-mac.zip | cut -f1 -d' ')
qtexpsum="214d22d8572ea6162753c8dd251d79275f3b22d49204718c637d722409e0cfcb"
if [ "$qtsum" != "$qtexpsum" ]; then
echo "Qt hash $qtsum does not match $qtexpsum"
exit 1
fi
sudo mkdir -p /opt || exit 1
cd /opt || exit 1
sudo unzip -q /tmp/qt-5.6.3-static-mac.zip || exit 1
cd - || exit 1
fi
export PATH="/opt/qt56sm/bin:$PATH"
elif [ "$UPLATFORM" = "win32" ]; then
# Install missing dependencies
pacman -S --noconfirm --needed zip unzip curl perl mingw-w64-i686-toolchain mingw-w64-i686-cmake || exit 1
# Fix PATH to support running shasum.
export PATH="/usr/bin/core_perl:$PATH"
if [ ! -d "/c/Qt/5.6/mingw49_32_release_static/" ]; then
curl -L -o /tmp/qt-5.6.3-static-win32.zip https://github.com/distdb/qtbuilds/blob/master/qt-5.6.3-static-win32.zip?raw=true || exit 1
qtsum=$(shasum -a 256 /tmp/qt-5.6.3-static-win32.zip | cut -f1 -d' ')
qtexpsum="bcd85145d6fed00da37498c08c49d763c6fa883337f754880b5c786899e6bb1d"
if [ "$qtsum" != "$qtexpsum" ]; then
echo "Qt hash $qtsum does not match $qtexpsum"
exit 1
fi
mkdir -p /c/Qt/5.6 || exit 1
cd /c/Qt/5.6 || exit 1
unzip -q /tmp/qt-5.6.3-static-win32.zip || exit 1
cd - || exit 1
fi
export PATH="/c/Qt/5.6/mingw49_32_release_static/bin:$PATH"
fi
echo "Attempting to build UEFITool NE for ${UPLATFORM}..."
UEFITOOL_VER=$(cat UEFITool/uefitool.cpp | grep ^version | cut -d'"' -f2 | sed 's/NE alpha /A/')
UEFIDUMP_VER=$(cat UEFIDump/uefidump_main.cpp | grep '"UEFIDump [0-9]' | cut -d'"' -f2 | cut -d' ' -f2)
UEFIEXTRACT_VER=$(cat UEFIExtract/uefiextract_main.cpp | grep '"UEFIExtract [0-9]' | cut -d'"' -f2 | cut -d' ' -f2)
UEFIFIND_VER=$(cat UEFIFind/uefifind_main.cpp | grep '"UEFIFind [0-9]' | cut -d'"' -f2 | cut -d' ' -f2)
build_tool() {
echo "Building $1 $2"
# Check version
if [ "$(echo "$2" | grep '^[0-9]*\.[0-9]*\.[0-9]*$')" != "$2" ] && [ "$(echo "$2" | grep '^A[0-9]*$')" != "$2" ]; then
echo "Invalid $1 version!"
exit 1
fi
# Tools are in subdirectories
cd "$1" || exit 1
# Build
if [ "$3" != "" ]; then
# -flto is flawed on CI atm
if [ "$UPLATFORM" = "mac" ]; then
qmake $3 QMAKE_CXXFLAGS+=-flto QMAKE_LFLAGS+=-flto CONFIG+=optimize_size || exit 1
elif [ "$UPLATFORM" = "win32" ]; then
qmake $3 QMAKE_CXXFLAGS="-static -flto -Os" QMAKE_LFLAGS="-static -flto -Os" CONFIG+=optimize_size CONFIG+=staticlib CONFIG+=static || exit 1
else
qmake $3 CONFIG+=optimize_size || exit 1
fi
else
if [ "$UPLATFORM" = "mac" ]; then
cmake -G "Unix Makefiles" -DCMAKE_CXX_FLAGS="-stdlib=libc++ -flto -Os -mmacosx-version-min=10.7" -DCMAKE_C_FLAGS="-flto -Os -mmacosx-version-min=10.7" || exit 1
elif [ "$UPLATFORM" = "win32" ]; then
cmake -G "Unix Makefiles" -DCMAKE_CXX_FLAGS="-static -Os" -DCMAKE_C_FLAGS="-static -Os" || exit 1
else
cmake -G "Unix Makefiles" -DCMAKE_CXX_FLAGS="-Os" -DCMAKE_C_FLAGS="-Os" || exit 1
fi
fi
make || exit 1
# Move the binary out of the dir
if [ "$UPLATFORM" = "win32" ] && [ -f "release/${1}${BINSUFFIX}" ]; then
mv "release/${1}${BINSUFFIX}" "${1}${BINSUFFIX}" || exit 1
fi
# Archive
if [ "$1" = "UEFITool" ] && [ "$UPLATFORM" = "mac" ]; then
strip -x UEFITool.app/Contents/MacOS/UEFITool || exit 1
zip -qry ../dist/"${1}_NE_${2}_${UPLATFORM}.zip" UEFITool.app ${4} || exit 1
else
strip -x "${1}${BINSUFFIX}" || exit 1
zip -qry ../dist/"${1}_NE_${2}_${UPLATFORM}.zip" "${1}${BINSUFFIX}" ${4} || exit 1
fi
# Return to parent
cd - || exit 1
}
rm -rf dist
mkdir -p dist || exit 1
build_tool UEFITool "$UEFITOOL_VER" uefitool.pro
build_tool UEFIDump "$UEFIDUMP_VER" ""
build_tool UEFIExtract "$UEFIEXTRACT_VER" uefiextract.pro
build_tool UEFIFind "$UEFIFIND_VER" uefifind.pro
exit 0