Merge Qt/non-Qt codebase

- added UEFIDump tool, which is now Windows-only UEFIExtract with some
limitations, made as PoC for non-Qt engine usage
- ensured that Qt classes will be used, if available
- checked build of UT and UE
- porting of UEFIFind to non-Qt engine TBD
This commit is contained in:
Nikolaj Schlej 2016-07-07 07:57:45 +02:00
parent 12029c768c
commit 9045fc6cc0
22 changed files with 612 additions and 250 deletions

49
UEFIDump/CMakeLists.txt Normal file
View file

@ -0,0 +1,49 @@
PROJECT(UEFIDump)
SET(PROJECT_SOURCES
uefidump_main.cpp
uefidump.cpp
../common/types.cpp
../common/descriptor.cpp
../common/ffs.cpp
../common/nvram.cpp
../common/ffsparser.cpp
../common/ffsreport.cpp
../common/fitparser.cpp
../common/peimage.cpp
../common/treeitem.cpp
../common/treemodel.cpp
../common/utility.cpp
../common/LZMA/LzmaDecompress.c
../common/LZMA/SDK/C/LzmaDec.c
../common/Tiano/EfiTianoDecompress.c
../common/ustring.cpp
../bstrlib/bstrlib.c
../bstrlib/bstrwrap.cpp
)
SET(PROJECT_HEADERS
uefidump.h
../common/basetypes.h
../common/descriptor.h
../common/gbe.h
../common/me.h
../common/ffs.h
../common/nvram.h
../common/ffsparser.h
../common/ffsreport.h
../common/fitparser.h
../common/peimage.h
../common/types.h
../common/treeitem.h
../common/treemodel.h
../common/utility.h
../common/LZMA/LzmaDecompress.h
../common/Tiano/EfiTianoDecompress.h
../common/ubytearray.h
../common/ustring.h
../bstrlib/bstrlib.h
../bstrlib/bstrwrap.h
)
ADD_EXECUTABLE(UEFIDump ${PROJECT_SOURCES} ${PROJECT_HEADERS})

234
UEFIDump/uefidump.cpp Normal file
View file

@ -0,0 +1,234 @@
/* ffsdumper.cpp
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <windows.h>
#include "uefidump.h"
#include "../common/ffs.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
USTATUS UEFIDumper::dump(const UByteArray & buffer, const std::wstring & inPath, const std::wstring & guid)
{
//TODO: rework to support relative paths
std::wstring path = std::wstring(inPath).append(L".dump2");
path = L"\\\\?\\" + path;
std::wstring reportPath = std::wstring(inPath).append(L".report2.txt");
reportPath = L"\\\\?\\" + reportPath;
std::wcout << L"Dump path: " << path << std::endl;
std::wcout << L"Report path: " << reportPath << std::endl;
if (initialized) {
// Check if called with a different buffer as before
if (buffer != currentBuffer) {
// Reinitalize if so
initialized = false;
}
}
if (!initialized) {
// Fill currentBuffer
currentBuffer = buffer;
// Parse FFS structure
USTATUS result = ffsParser.parse(buffer);
if (result)
return result;
// Show ffsParser messages
std::vector<std::pair<UString, UModelIndex> > messages = ffsParser.getMessages();
for (size_t i = 0; i < messages.size(); i++) {
std::cout << messages[i].first << std::endl;
}
// Get last VTF
UModelIndex lastVtf = ffsParser.getLastVtf();
if (lastVtf.isValid()) {
// Create fitParser
FitParser fitParser(&model);
// Find and parse FIT table
result = fitParser.parse(model.index(0, 0), lastVtf);
if (U_SUCCESS == result) {
// Show fitParser's messages
std::vector<std::pair<UString, UModelIndex> > fitMessages = fitParser.getMessages();
for (size_t i = 0; i < fitMessages.size(); i++) {
std::cout << (const char*)fitMessages[i].first.toLocal8Bit() << std::endl;
}
// Show FIT table
std::vector<std::vector<UString> > fitTable = fitParser.getFitTable();
if (fitTable.size()) {
std::cout << "-------------------------------------------------------------------" << std::endl;
std::cout << " Address | Size | Ver | Type | CS " << std::endl;
std::cout << "-------------------------------------------------------------------" << std::endl;
for (size_t i = 0; i < fitTable.size(); i++) {
std::cout << (const char*)fitTable[i][0].toLocal8Bit() << " | "
<< (const char*)fitTable[i][1].toLocal8Bit() << " | "
<< (const char*)fitTable[i][2].toLocal8Bit() << " | "
<< (const char*)fitTable[i][3].toLocal8Bit() << " | "
<< (const char*)fitTable[i][4].toLocal8Bit() << std::endl;
}
}
}
}
// Create ffsReport
FfsReport ffsReport(&model);
std::vector<UString> report = ffsReport.generate();
if (report.size()) {
std::ofstream ofs;
ofs.open(reportPath, std::ofstream::out);
for (size_t i = 0; i < report.size(); i++) {
ofs << (const char*)report[i].toLocal8Bit() << std::endl;
}
ofs.close();
}
initialized = true;
}
dumped = false;
UINT8 result = recursiveDump(model.index(0,0), path, guid);
if (result)
return result;
else if (!dumped)
return U_ITEM_NOT_FOUND;
return U_SUCCESS;
}
std::wstring UEFIDumper::guidToWstring(const EFI_GUID & guid)
{
std::wstringstream ws;
ws << std::hex << std::uppercase << std::setfill(L'0');
ws << std::setw(8) << *(const UINT32*)&guid.Data[0] << L"-";
ws << std::setw(4) << *(const UINT16*)&guid.Data[4] << L"-";
ws << std::setw(4) << *(const UINT16*)&guid.Data[6] << L"-";
ws << std::setw(2) << guid.Data[8];
ws << std::setw(2) << guid.Data[9] << L"-";
ws << std::setw(2) << guid.Data[10];
ws << std::setw(2) << guid.Data[11];
ws << std::setw(2) << guid.Data[12];
ws << std::setw(2) << guid.Data[13];
ws << std::setw(2) << guid.Data[14];
ws << std::setw(2) << guid.Data[15];
return ws.str();
}
bool UEFIDumper::createFullPath(const std::wstring & path) {
// Break the path into parent\current, assuming the path is already full and converted into Windows native "\\?\" format
size_t pos = path.find_last_of(L'\\');
// Slash is not found, it's a bug
if (pos == path.npos)
return FALSE;
std::wstring parent = path.substr(0, pos);
std::wstring current = path.substr(pos + 1);
// Check if first exist, if so, create last and return true
UINT32 attributes = GetFileAttributesW(parent.c_str());
if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
// first is already exist, just create last
return CreateDirectoryW(path.c_str(), NULL) != 0;
}
// Perform recursive call
if (createFullPath(parent))
return CreateDirectoryW(path.c_str(), NULL) != 0;
return FALSE;
}
USTATUS UEFIDumper::recursiveDump(const UModelIndex & index, const std::wstring & path, const std::wstring & guid)
{
if (!index.isValid())
return U_INVALID_PARAMETER;
UByteArray itemHeader = model.header(index);
UByteArray fileHeader = model.header(model.findParentOfType(index, Types::File));
if (guid.length() == 0 ||
(itemHeader.size() >= sizeof (EFI_GUID) && guidToWstring(*(const EFI_GUID*)itemHeader.constData()) == guid) ||
(fileHeader.size() >= sizeof(EFI_GUID) && guidToWstring(*(const EFI_GUID*)fileHeader.constData()) == guid)) {
if (SetCurrentDirectoryW(path.c_str()))
return U_DIR_ALREADY_EXIST;
if (!createFullPath(path))
return U_DIR_CREATE;
//if (model.rowCount(index) == 0) {
// Header
UByteArray data = model.header(index);
if (!data.isEmpty()) {
std::ofstream file;
std::wstring name = path + std::wstring(L"\\header.bin");
file.open(name, std::ios::out | std::ios::binary);
file.write(data.constData(), data.size());
file.close();
}
// Body
data = model.body(index);
if (!data.isEmpty()) {
std::ofstream file;
std::wstring name = path + std::wstring(L"\\body.bin");
file.open(name, std::ios::out | std::ios::binary);
file.write(data.constData(), data.size());
file.close();
}
//}
// Info
UString info = "Type: " + itemTypeToUString(model.type(index)) + "\n" +
"Subtype: " + itemSubtypeToUString(model.type(index), model.subtype(index)) + "\n";
if (model.text(index).length() > 0)
info += "Text: " + model.text(index) + "\n";
info += model.info(index) + "\n";
std::ofstream file;
std::wstring name = path + std::wstring(L"\\info.txt");
file.open(name, std::ios::out);
file.write((const char*)info, info.length());
file.close();
dumped = true;
}
UINT8 result;
for (int i = 0; i < model.rowCount(index); i++) {
UModelIndex childIndex = index.child(i, 0);
bool useText = false;
if (model.type(childIndex) != Types::Volume)
useText = (model.text(childIndex).length() > 0);
UString name = useText ? (const char *)model.text(childIndex) : (const char *)model.name(childIndex);
std::string sName = std::string((const char*)name, name.length());
std::wstring childPath = path + std::wstring(L"\\") + std::to_wstring(i) + std::wstring(L" ") + std::wstring(sName.begin(), sName.end());
// Workaround for paths with dot at the end, just add remove it
if (childPath.at(childPath.length() - 1) == L'.')
childPath.pop_back();
result = recursiveDump(childIndex, childPath, guid);
if (result)
return result;
}
return U_SUCCESS;
}

50
UEFIDump/uefidump.h Normal file
View file

@ -0,0 +1,50 @@
/* uefidump.h
Copyright (c) 2016, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef UEFIDUMP_H
#define UEFIDUMP_H
#include <string>
#include "../common/basetypes.h"
#include "../common/ustring.h"
#include "../common/treemodel.h"
#include "../common/ffsparser.h"
#include "../common/ffsreport.h"
#include "../common/fitparser.h"
class UEFIDumper
{
public:
explicit UEFIDumper() : model(), ffsParser(&model), ffsReport(&model), fitParser(&model), currentBuffer(), initialized(false), dumped(false) {}
~UEFIDumper() {}
USTATUS dump(const UByteArray & buffer, const std::wstring & path, const std::wstring & guid = std::wstring());
private:
USTATUS recursiveDump(const UModelIndex & root, const std::wstring & path, const std::wstring & guid);
std::wstring guidToWstring(const EFI_GUID & guid);
bool createFullPath(const std::wstring & path);
TreeModel model;
FfsParser ffsParser;
FfsReport ffsReport;
FitParser fitParser;
UByteArray currentBuffer;
bool initialized;
bool dumped;
};
#endif

View file

@ -0,0 +1,43 @@
/* uefidump_main.cpp
Copyright (c) 2016, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <iostream>
#include <fstream>
#include "uefidump.h"
int wmain(int argc, wchar_t *argv[])
{
if (argc > 32) {
std::cout << "Too many arguments" << std::endl;
return 1;
}
if (argc > 1) {
std::ifstream inputFile;
inputFile.open(argv[1], std::ios::in | std::ios::binary);
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
(std::istreambuf_iterator<char>()));
inputFile.close();
UEFIDumper uefidumper;
return (uefidumper.dump(buffer, std::wstring(argv[1])) != U_SUCCESS);
}
else {
std::cout << "UEFIDump 0.1.0" << std::endl << std::endl
<< "Usage: UEFIExtract imagefile " << 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

@ -23,9 +23,7 @@ SOURCES += \
../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/LzmaDec.c \
../common/Tiano/EfiTianoDecompress.c \
../common/ustring.cpp \
../bstrlib/bstrlib.c \
../bstrlib/bstrwrap.cpp
../common/ustring.cpp
HEADERS += \
ffsdumper.h \
@ -46,7 +44,5 @@ HEADERS += \
../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \
../common/ubytearray.h \
../common/ustring.h \
../bstrlib/bstrlib.h \
../bstrlib/bstrwrap.h
../common/ustring.h

View file

@ -20,6 +20,7 @@ SOURCES += uefifind_main.cpp \
../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/LzmaDec.c \
../common/Tiano/EfiTianoDecompress.c \
../common/ustring.cpp
HEADERS += uefifind.h \
../common/basetypes.h \
@ -35,5 +36,7 @@ HEADERS += uefifind.h \
../common/treemodel.h \
../common/utility.h \
../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h
../common/Tiano/EfiTianoDecompress.h \
../common/ustring.h \
../common/ubytearray.h

View file

@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsfinder.h"
STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode)
USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode)
{
if (!index.isValid())
return ERR_SUCCESS;
return U_SUCCESS;
if (hexPattern.isEmpty())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length())
return ERR_SUCCESS;
return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
findHexPattern(index.child(i, index.column()), hexPattern, mode);
}
QByteArray data;
UByteArray data;
if (hasChildren) {
if (mode != SEARCH_MODE_BODY)
data = model->header(index);
@ -44,39 +44,37 @@ STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & h
data.append(model->header(index)).append(model->body(index));
}
QString hexBody = QString(data.toHex());
QRegExp regexp = QRegExp(QString(hexPattern), Qt::CaseInsensitive);
UString hexBody = UString(data.toHex());
QRegExp regexp = QRegExp(UString(hexPattern), Qt::CaseInsensitive);
INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) {
if (offset % 2 == 0) {
msg(QObject::tr("Hex pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
.arg(QString(hexPattern))
.arg(hexBody.mid(offset, hexPattern.length()).toUpper())
.arg(model->name(index))
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2),
msg(UString("Hex pattern \"") + UString(hexPattern)
+ UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
+ UString("\" in ") + model->name(index)
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
index);
}
offset = regexp.indexIn(hexBody, offset + 1);
}
return ERR_SUCCESS;
return U_SUCCESS;
}
STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode)
USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode)
{
if (guidPattern.isEmpty())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
if (!index.isValid())
return ERR_SUCCESS;
return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
findGuidPattern(index.child(i, index.column()), guidPattern, mode);
}
QByteArray data;
UByteArray data;
if (hasChildren) {
if (mode != SEARCH_MODE_BODY)
data = model->header(index);
@ -90,12 +88,12 @@ STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray &
data.append(model->header(index)).append(model->body(index));
}
QString hexBody = QString(data.toHex());
QList<QByteArray> list = guidPattern.split('-');
UString hexBody = UString(data.toHex());
QList<UByteArray> list = guidPattern.split('-');
if (list.count() != 5)
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
QByteArray hexPattern;
UByteArray hexPattern;
// Reverse first GUID block
hexPattern.append(list.at(0).mid(6, 2));
hexPattern.append(list.at(0).mid(4, 2));
@ -112,40 +110,38 @@ STATUS FfsFinder::findGuidPattern(const QModelIndex & index, const QByteArray &
// Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length())
return ERR_SUCCESS;
return U_SUCCESS;
QRegExp regexp(QString(hexPattern), Qt::CaseInsensitive);
QRegExp regexp(UString(hexPattern), Qt::CaseInsensitive);
INT32 offset = regexp.indexIn(hexBody);
while (offset >= 0) {
if (offset % 2 == 0) {
msg(QObject::tr("GUID pattern \"%1\" found as \"%2\" in %3 at %4-offset %5h")
.arg(QString(guidPattern))
.arg(hexBody.mid(offset, hexPattern.length()).toUpper())
.arg(model->name(index))
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(offset / 2),
msg(UString("GUID pattern \"") + UString(guidPattern)
+ UString("\" found as \"") + hexBody.mid(offset, hexPattern.length()).toUpper()
+ UString("\" in ") + model->name(index)
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
index);
}
offset = regexp.indexIn(hexBody, offset + 1);
}
return ERR_SUCCESS;
return U_SUCCESS;
}
STATUS FfsFinder::findTextPattern(const QModelIndex & index, const QString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
{
if (pattern.isEmpty())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
if (!index.isValid())
return ERR_SUCCESS;
return U_SUCCESS;
bool hasChildren = (model->rowCount(index) > 0);
for (int i = 0; i < model->rowCount(index); i++) {
findTextPattern(index.child(i, index.column()), pattern, mode, unicode, caseSensitive);
}
QByteArray body;
UByteArray body;
if (hasChildren) {
if (mode != SEARCH_MODE_BODY)
body = model->header(index);
@ -159,22 +155,20 @@ STATUS FfsFinder::findTextPattern(const QModelIndex & index, const QString & pat
body.append(model->header(index)).append(model->body(index));
}
QString data;
UString data;
if (unicode)
data = QString::fromUtf16((const ushort*)body.constData(), body.length() / 2);
data = UString::fromUtf16((const ushort*)body.constData(), body.length() / 2);
else
data = QString::fromLatin1((const char*)body.constData(), body.length());
data = UString::fromLatin1((const char*)body.constData(), body.length());
int offset = -1;
while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) {
msg(QObject::tr("%1 text \"%2\" found in %3 at %4-offset %5h")
.arg(unicode ? "Unicode" : "ASCII")
.arg(pattern)
.arg(model->name(index))
.arg(mode == SEARCH_MODE_BODY ? QObject::tr("body") : QObject::tr("header"))
.hexarg(unicode ? offset * 2 : offset),
msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + UString(pattern)
+ UString("\" found in ") + model->name(index)
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", (unicode ? offset * 2 : offset)),
index);
}
return ERR_SUCCESS;
return U_SUCCESS;
}

View file

@ -15,13 +15,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define FFSFINDER_H
#include <vector>
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QModelIndex>
#include <QRegExp>
#include "../common/ubytearray.h"
#include "../common/ustring.h"
#include "../common/basetypes.h"
#include "../common/treemodel.h"
@ -31,19 +28,19 @@ public:
FfsFinder(const TreeModel * treeModel) : model(treeModel) {}
~FfsFinder() {}
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
void clearMessages() { messagesVector.clear(); }
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode);
STATUS findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode);
STATUS findTextPattern(const QModelIndex & index, const QString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode);
USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode);
USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
private:
const TreeModel* model;
std::vector<std::pair<QString, QModelIndex> > messagesVector;
std::vector<std::pair<UString, UModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}
};

View file

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
version(tr("0.30.0_alpha28"))
version(tr("0.30.0_alpha29"))
{
clipboard = QApplication::clipboard();
@ -211,7 +211,7 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex &current)
if (current.isValid() && model->type(current) == Types::Section &&
(model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) {
// Get parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(current);
PARSING_DATA pdata = parsingDataFromUModelIndex(current);
if (model->subtype(current) == EFI_SECTION_COMPRESSION &&
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE &&
@ -297,7 +297,7 @@ void UEFITool::goToData()
QModelIndex parent = model->parent(index);
for (int i = index.row(); i < model->rowCount(parent); i++) {
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0;
if (pdata.nvar.next == lastVariableFlag) {
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
@ -306,7 +306,7 @@ void UEFITool::goToData()
for (int j = i + 1; j < model->rowCount(parent); j++) {
QModelIndex currentIndex = parent.child(j, 0);
PARSING_DATA currentPdata = parsingDataFromQModelIndex(currentIndex);
PARSING_DATA currentPdata = parsingDataFromUModelIndex(currentIndex);
if (currentPdata.offset == pdata.offset + pdata.nvar.next) {
index = currentIndex;
break;
@ -481,7 +481,7 @@ void UEFITool::replace(const UINT8 mode)
UINT8 result = ffsOps->replace(index, buffer, mode);
if (result) {
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToQString(result), QMessageBox::Ok);
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
return;
}
ui->actionSaveImageFile->setEnabled(true);
@ -512,7 +512,7 @@ void UEFITool::extract(const UINT8 mode)
QString name;
UINT8 result = ffsOps->extract(index, name, extracted, mode);
if (result) {
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToQString(result), QMessageBox::Ok);
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok);
return;
}
@ -609,21 +609,21 @@ void UEFITool::extract(const UINT8 mode)
void UEFITool::rebuild()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
if (ERR_SUCCESS == ffsOps->rebuild(index))
if (U_SUCCESS == ffsOps->rebuild(index))
ui->actionSaveImageFile->setEnabled(true);
}
void UEFITool::remove()
{
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
if (!index.isValid())
return;
if (ERR_SUCCESS == ffsOps->remove(index))
if (U_SUCCESS == ffsOps->remove(index))
ui->actionSaveImageFile->setEnabled(true);
}
@ -661,10 +661,10 @@ void UEFITool::saveImageFile()
// Create ffsBuilder
delete ffsBuilder;
ffsBuilder = new FfsBuilder(model);
STATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
showBuilderMessages();
if (result) {
QMessageBox::critical(this, tr("Image build failed"), errorCodeToQString(result), QMessageBox::Ok);
QMessageBox::critical(this, tr("Image build failed"), errorCodeToUString(result), QMessageBox::Ok);
return;
}
@ -725,7 +725,7 @@ void UEFITool::openImageFile(QString path)
UINT8 result = ffsParser->parse(buffer);
showParserMessages();
if (result) {
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToQString(result), QMessageBox::Ok);
QMessageBox::critical(this, tr("Image parsing failed"), errorCodeToUString(result), QMessageBox::Ok);
return;
}
else

View file

@ -29,7 +29,8 @@ SOURCES += uefitool_main.cpp \
../common/LZMA/SDK/C/LzmaEnc.c \
../common/Tiano/EfiTianoDecompress.c \
../common/Tiano/EfiTianoCompress.c \
../common/Tiano/EfiTianoCompressLegacy.c
../common/Tiano/EfiTianoCompressLegacy.c \
../common/ustring.cpp \
HEADERS += uefitool.h \
searchdialog.h \
@ -56,7 +57,9 @@ HEADERS += uefitool.h \
../common/LZMA/LzmaCompress.h \
../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \
../common/Tiano/EfiTianoCompress.h
../common/Tiano/EfiTianoCompress.h \
../common/ustring.h \
../common/ubytearray.h \
FORMS += uefitool.ui \
searchdialog.ui

View file

@ -75,7 +75,7 @@ UINT32 *DestinationSize
if (*DestinationSize < destLen)
{
*DestinationSize = destLen;
return ERR_BUFFER_TOO_SMALL;
return EFI_BUFFER_TOO_SMALL;
}
LzmaEncProps_Init(&props);
@ -101,9 +101,9 @@ UINT32 *DestinationSize
SetEncodedSizeOfBuf((UINT64)SourceSize, Destination);
if (LzmaResult == SZ_OK) {
return ERR_SUCCESS;
return EFI_SUCCESS;
}
else {
return ERR_INVALID_PARAMETER;
return EFI_INVALID_PARAMETER;
}
}

View file

@ -12,22 +12,22 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "ffsbuilder.h"
STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased)
USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
erased.fill(pdata.emptyByte);
return ERR_SUCCESS;
return U_SUCCESS;
}
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
USTATUS FfsBuilder::build(const UModelIndex & root, UByteArray & image)
{
// Sanity check
if (!root.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
if (model->type(root) == Types::Capsule) {
return buildCapsule(root, image);
@ -41,44 +41,44 @@ STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
}
}
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// No action required
if (model->action(index) == Actions::NoAction) {
// Use original item data
capsule = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Rebuild or Replace
else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) {
if (model->rowCount(index)) {
// Clear the supplied QByteArray
// Clear the supplied UByteArray
capsule.clear();
// Right now there is only one capsule image element supported
if (model->rowCount(index) != 1) {
msg(QObject::tr("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
//msg(UString("buildCapsule: building of capsules with %1 elements are not supported, original item data is used").arg(model->rowCount(index)), index);
// Use original item data
capsule = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Build image
QModelIndex imageIndex = index.child(0, 0);
QByteArray imageData;
UModelIndex imageIndex = index.child(0, 0);
UByteArray imageData;
// Check image type
if (model->type(imageIndex) == Types::Image) {
STATUS result = ERR_SUCCESS;
USTATUS result = U_SUCCESS;
if (model->subtype(imageIndex) == Subtypes::IntelImage) {
result = buildIntelImage(imageIndex, imageData);
}
@ -86,20 +86,20 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
result = buildRawArea(imageIndex, imageData);
}
else {
msg(QObject::tr("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
//msg(UString("buildCapsule: unexpected item of subtype %1 can't be processed, original item data is used").arg(model->subtype(imageIndex)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
}
// Check build result
if (result) {
msg(QObject::tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToQString(result)), imageIndex);
//msg(UString("buildCapsule: building of \"%1\" failed with error \"%2\", original item data is used").arg(model->name(imageIndex)).arg(errorCodeToUString(result)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
}
else
capsule.append(imageData);
}
else {
msg(QObject::tr("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
//msg(UString("buildCapsule: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(imageIndex)), imageIndex);
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
}
@ -107,14 +107,14 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
UINT32 newSize = capsule.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
return U_INVALID_PARAMETER;
}
else if (newSize < oldSize) {
msg(QObject::tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return U_INVALID_PARAMETER;
}
}
else
@ -122,23 +122,23 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
// Build successful, append header
capsule = model->header(index).append(capsule);
return ERR_SUCCESS;
return U_SUCCESS;
}
msg(QObject::tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intelImage)
USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & intelImage)
{
// Sanity check
if (!index.isValid())
return ERR_SUCCESS;
return U_SUCCESS;
// No action
if (model->action(index) == Actions::NoAction) {
intelImage = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Rebuild
@ -150,7 +150,7 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
// Process other regions
for (int i = 1; i < model->rowCount(index); i++) {
QModelIndex currentRegion = index.child(i, 0);
UModelIndex currentRegion = index.child(i, 0);
// Skip regions with Remove action
if (model->action(currentRegion) == Actions::Remove)
@ -165,15 +165,15 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
}
// Check region subtype
STATUS result;
QByteArray region;
USTATUS result;
UByteArray region;
UINT8 regionType = model->subtype(currentRegion);
switch (regionType) {
case Subtypes::BiosRegion:
case Subtypes::PdrRegion:
result = buildRawArea(currentRegion, region);
if (result) {
msg(QObject::tr("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
//msg(UString("buildIntelImage: building of %1 region failed with error \"%2\", original item data is used").arg(regionTypeToQString(regionType)).arg(errorCodeToQString(result)), currentRegion);
region = model->header(currentRegion).append(model->body(currentRegion));
}
break;
@ -188,8 +188,8 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
region = model->header(currentRegion).append(model->body(currentRegion));
break;
default:
msg(QObject::tr("buildIntelImage: don't know how to build region of unknown type"), index);
return ERR_UNKNOWN_ITEM_TYPE;
msg(UString("buildIntelImage: don't know how to build region of unknown type"), index);
return U_UNKNOWN_ITEM_TYPE;
}
// Append the resulting region
@ -200,48 +200,48 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
UINT32 newSize = intelImage.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildIntelImage: new image size %1h (%2) is bigger than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return U_INVALID_PARAMETER;
}
else if (newSize < oldSize) {
msg(QObject::tr("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildIntelImage: new image size %1h (%2) is smaller than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return U_INVALID_PARAMETER;
}
// Reconstruction successful
return ERR_SUCCESS;
return U_SUCCESS;
}
msg(QObject::tr("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildIntelImage: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader)
USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// No action required
if (model->action(index) == Actions::NoAction) {
rawArea = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Rebuild or Replace
else if (model->action(index) == Actions::Rebuild
|| model->action(index) == Actions::Replace) {
if (model->rowCount(index)) {
// Clear the supplied QByteArray
// Clear the supplied UByteArray
rawArea.clear();
// Build children
for (int i = 0; i < model->rowCount(index); i++) {
STATUS result = ERR_SUCCESS;
QModelIndex currentChild = index.child(i, 0);
QByteArray currentData;
USTATUS result = U_SUCCESS;
UModelIndex currentChild = index.child(i, 0);
UByteArray currentData;
// Check child type
if (model->type(currentChild) == Types::Volume) {
result = buildVolume(currentChild, currentData);
@ -250,12 +250,12 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
result = buildPadding(currentChild, currentData);
}
else {
msg(QObject::tr("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
//msg(UString("buildRawArea: unexpected item of type %1 can't be processed, original item data is used").arg(model->type(currentChild)), currentChild);
currentData = model->header(currentChild).append(model->body(currentChild));
}
// Check build result
if (result) {
msg(QObject::tr("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
//msg(UString("buildRawArea: building of %1 failed with error \"%2\", original item data is used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
currentData = model->header(currentChild).append(model->body(currentChild));
}
// Append current data
@ -266,14 +266,14 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
UINT32 newSize = rawArea.size();
UINT32 oldSize = model->body(index).size();
if (newSize > oldSize) {
msg(QObject::tr("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildRawArea: new area size %1h (%2) is bigger than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return U_INVALID_PARAMETER;
}
else if (newSize < oldSize) {
msg(QObject::tr("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return ERR_INVALID_PARAMETER;
//msg(UString("buildRawArea: new area size %1h (%2) is smaller than the original %3h (%4)")
// .hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
return U_INVALID_PARAMETER;
}
}
else
@ -282,95 +282,95 @@ STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea,
// Build successful, add header if needed
if (addHeader)
rawArea = model->header(index).append(rawArea);
return ERR_SUCCESS;
return U_SUCCESS;
}
msg(QObject::tr("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
USTATUS FfsBuilder::buildPadding(const UModelIndex & index, UByteArray & padding)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// No action required
if (model->action(index) == Actions::NoAction) {
padding = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Erase
else if (model->action(index) == Actions::Erase) {
padding = model->header(index).append(model->body(index));
if(erase(index, padding))
msg(QObject::tr("buildPadding: erase failed, original item data is used"), index);
return ERR_SUCCESS;
msg(UString("buildPadding: erase failed, original item data is used"), index);
return U_SUCCESS;
}
msg(QObject::tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildPadding: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data)
USTATUS FfsBuilder::buildNonUefiData(const UModelIndex & index, UByteArray & data)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// No action required
if (model->action(index) == Actions::NoAction) {
data = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
// Erase
else if (model->action(index) == Actions::Erase) {
data = model->header(index).append(model->body(index));
if (erase(index, data))
msg(QObject::tr("buildNonUefiData: erase failed, original item data is used"), index);
return ERR_SUCCESS;
msg(UString("buildNonUefiData: erase failed, original item data is used"), index);
return U_SUCCESS;
}
msg(QObject::tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToUString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace)
USTATUS FfsBuilder::buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// No action required
if (model->action(index) == Actions::NoAction) {
freeSpace = model->header(index).append(model->body(index));
return ERR_SUCCESS;
return U_SUCCESS;
}
msg(QObject::tr("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return ERR_NOT_IMPLEMENTED;
//msg(UString("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildVolume(const QModelIndex & index, QByteArray & volume)
USTATUS FfsBuilder::buildVolume(const UModelIndex & index, UByteArray & volume)
{
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildPadFile(const QModelIndex & index, QByteArray & padFile)
USTATUS FfsBuilder::buildPadFile(const UModelIndex & index, UByteArray & padFile)
{
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildFile(const QModelIndex & index, QByteArray & file)
USTATUS FfsBuilder::buildFile(const UModelIndex & index, UByteArray & file)
{
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
STATUS FfsBuilder::buildSection(const QModelIndex & index, QByteArray & section)
USTATUS FfsBuilder::buildSection(const UModelIndex & index, UByteArray & section)
{
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}

View file

@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <vector>
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QModelIndex>
#include "ubytearray.h"
#include "ustring.h"
#include "basetypes.h"
#include "treemodel.h"
#include "descriptor.h"
@ -33,31 +30,31 @@ public:
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
~FfsBuilder() {}
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
void clearMessages() { messagesVector.clear(); }
STATUS build(const QModelIndex & root, QByteArray & image);
USTATUS build(const UModelIndex & root, UByteArray & image);
private:
const TreeModel* model;
std::vector<std::pair<QString, QModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
std::vector<std::pair<UString, UModelIndex> > messagesVector;
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true);
STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
STATUS buildVolume(const QModelIndex & index, QByteArray & volume);
STATUS buildNonUefiData(const QModelIndex & index, QByteArray & data);
STATUS buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace);
STATUS buildPadFile(const QModelIndex & index, QByteArray & padFile);
STATUS buildFile(const QModelIndex & index, QByteArray & file);
STATUS buildSection(const QModelIndex & index, QByteArray & section);
USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool addHeader = true);
USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
USTATUS buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace);
USTATUS buildPadFile(const UModelIndex & index, UByteArray & padFile);
USTATUS buildFile(const UModelIndex & index, UByteArray & file);
USTATUS buildSection(const UModelIndex & index, UByteArray & section);
// Utility functions
STATUS erase(const QModelIndex & index, QByteArray & erased);
USTATUS erase(const UModelIndex & index, UByteArray & erased);
};
#endif // FFSBUILDER_H

View file

@ -13,24 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ffsops.h"
STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode)
USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// Get data from parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
// Construct a name for extracted data
QString itemName = model->name(index);
QString itemText = model->text(index);
UString itemName = model->name(index);
UString itemText = model->text(index);
// Default name
name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_');
switch (model->type(index)) {
case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToQString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break;
case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToUString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break;
case Types::NvarEntry:
case Types::VssEntry:
case Types::FsysEntry:
@ -39,11 +39,11 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
case Types::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break;
case Types::Section: {
// Get parent file name
QModelIndex fileIndex = model->findParentOfType(index, Types::File);
QString fileText = model->text(fileIndex);
UModelIndex fileIndex = model->findParentOfType(index, Types::File);
UString fileText = model->text(fileIndex);
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_');
// Append section subtype name
name += QChar('_') + itemName.replace(' ', '_');
name += '_' + itemName.replace(' ', '_');
} break;
}
@ -67,9 +67,9 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
extracted.clear();
// There is no need to redo decompression, we can use child items
for (int i = 0; i < model->rowCount(index); i++) {
QModelIndex childIndex = index.child(i, 0);
UModelIndex childIndex = index.child(i, 0);
// Ensure 4-byte alignment of current section
extracted.append(QByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size()));
extracted.append(UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size()));
// Add current section header, body and tail
extracted.append(model->header(childIndex));
extracted.append(model->body(childIndex));
@ -77,49 +77,49 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
}
}
else
return ERR_UNKNOWN_EXTRACT_MODE;
return U_UNKNOWN_EXTRACT_MODE;
return ERR_SUCCESS;
return U_SUCCESS;
}
STATUS FfsOperations::replace(const QModelIndex & index, const QString & data, const UINT8 mode)
USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data, const UINT8 mode)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// Get data from parsing data
//PARSING_DATA pdata = parsingDataFromQModelIndex(index);
if (mode == REPLACE_MODE_AS_IS) {
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
else if (mode == REPLACE_MODE_BODY) {
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
else
return ERR_UNKNOWN_REPLACE_MODE;
return U_UNKNOWN_REPLACE_MODE;
return ERR_NOT_IMPLEMENTED;
return U_NOT_IMPLEMENTED;
}
STATUS FfsOperations::remove(const QModelIndex & index)
USTATUS FfsOperations::remove(const UModelIndex & index)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// Set remove action
model->setAction(index, Actions::Remove);
return ERR_SUCCESS;
return U_SUCCESS;
}
STATUS FfsOperations::rebuild(const QModelIndex & index)
USTATUS FfsOperations::rebuild(const UModelIndex & index)
{
// Sanity check
if (!index.isValid())
return ERR_INVALID_PARAMETER;
return U_INVALID_PARAMETER;
// On insert action, set insert action for children
//if (action == Actions::Insert)
@ -130,10 +130,10 @@ STATUS FfsOperations::rebuild(const QModelIndex & index)
model->setAction(index, Actions::Rebuild);
// Rebuild parent, if it has no action now
QModelIndex parent = index.parent();
UModelIndex parent = index.parent();
if (parent.isValid() && model->type(parent) != Types::Root
&& model->action(parent) == Actions::NoAction)
rebuild(parent);
return ERR_SUCCESS;
return U_SUCCESS;
}

View file

@ -16,11 +16,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <vector>
#include <QObject>
#include <QByteArray>
#include <QString>
#include <QModelIndex>
#include "ubytearray.h"
#include "ustring.h"
#include "basetypes.h"
#include "treemodel.h"
#include "ffs.h"
@ -33,21 +30,21 @@ public:
FfsOperations(TreeModel * treeModel) : model(treeModel) {}
~FfsOperations() {};
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
void clearMessages() { messagesVector.clear(); }
STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode);
STATUS replace(const QModelIndex & index, const QString & data, const UINT8 mode);
USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode);
USTATUS replace(const UModelIndex & index, const UString & data, const UINT8 mode);
STATUS remove(const QModelIndex & index);
STATUS rebuild(const QModelIndex & index);
USTATUS remove(const UModelIndex & index);
USTATUS rebuild(const UModelIndex & index);
private:
TreeModel* model;
std::vector<std::pair<QString, QModelIndex> > messagesVector;
std::vector<std::pair<UString, UModelIndex> > messagesVector;
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
}
};

View file

@ -1605,7 +1605,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 parentO
}
// Construct parsing data
bool fixed(fileHeader->Attributes & FFS_ATTRIB_FIXED);
bool fixed = (fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0;
pdata.offset += parentOffset;
@ -4543,7 +4543,7 @@ USTATUS FfsParser::parseFsysStoreBody(const UModelIndex & index)
pdata.offset = parentOffset + offset;
// Add tree item
model->addItem(Types::FsysEntry, 0, UString(name.constData(), name.size()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
model->addItem(Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), false, parsingDataToUByteArray(pdata), index);
// Move to next variable
offset += variableSize;

View file

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treeitem.h"
#include "treemodel.h"
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
#if defined(QT_CORE_LIB)
QVariant TreeModel::data(const UModelIndex &index, int role) const
{
if (!index.isValid())

View file

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef TREEMODEL_H
#define TREEMODEL_H
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
#if defined(QT_CORE_LIB)
// Use Qt classes
#include <QAbstractItemModel>
#include <QModelIndex>
@ -73,7 +73,7 @@ private:
};
#endif
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
#if defined(QT_CORE_LIB)
class TreeModel : public QAbstractItemModel
{
Q_OBJECT
@ -165,7 +165,7 @@ public:
UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const;
};
#if defined(QT_CORE_LIB) && defined(U_USE_QITEMMODEL)
#if defined(QT_CORE_LIB)
// Nothing required here
#else
inline UModelIndex UModelIndex::parent() const { return m ? m->parent(*this) : UModelIndex(); }

View file

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef UBYTEARRAY_H
#define UBYTEARRAY_H
#if defined(QT_CORE_LIB) && defined(U_USE_QBYTEARRAY)
#if defined(QT_CORE_LIB)
// Use Qt class, if Qt is available
#include <QByteArray>
#define UByteArray QByteArray
@ -60,14 +60,14 @@ public:
bool operator!= (const UByteArray & ba) const { return d != ba.d; }
inline void swap(UByteArray &other) { std::swap(d, other.d); }
UByteArray toHex() {
std::basic_string<char> hex(size() * 2, '\x00');
for (int32_t i = 0; i < size(); ++i) {
std::basic_string<char> hex(size() * 2, '\x00');
for (int32_t i = 0; i < size(); i++) {
uint8_t low = d[i] & 0x0F;
uint8_t high = (d[i] & 0xF0) >> 4;
low += (low < 10 ? 'a' : '0');
high += (high < 10 ? 'a' : '0');
hex[i] = low;
hex[i + 1] = high;
low += (low < 10 ? '0' : 'a');
high += (high < 10 ? '0' : 'a');
hex[2*i] = low;
hex[2*i + 1] = high;
}
std::reverse(hex.begin(), hex.end());
return UByteArray(hex);

View file

@ -13,9 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ustring.h"
#include <stdarg.h>
//TODO: modify properly
#if defined(QT_CORE_LIB) && defined (U_USE_QSTRING)
#if defined(QT_CORE_LIB)
UString usprintf(const char* fmt, ...)
{
UString msg;

View file

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef USTRING_H
#define USTRING_H
#if defined (QT_CORE_LIB) && defined(U_USE_QSTRING)
#if defined (QT_CORE_LIB)
// Use Qt class, if Qt is available
#include <QString>
#define UString QString

View file

@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define UTILITY_H
#include "ustring.h"
#include "treemodel.h"
#include "basetypes.h"
#include "parsingdata.h"