mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 16:08:23 +08:00
NE_alpha3
- some work done on ffsBuilder, still much to do - added more PE types - better names for utility.h functions
This commit is contained in:
parent
b429c74bcf
commit
8f7cc0d20e
@ -44,7 +44,7 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get data from parsing data
|
// Get data from parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
|
|
||||||
// Construct a name for extracted data
|
// Construct a name for extracted data
|
||||||
QString itemName = model->name(index);
|
QString itemName = model->name(index);
|
||||||
|
@ -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("0.30.0_alpha2"))
|
version(tr("0.30.0_alpha3"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ void UEFITool::openImageFile(QString path)
|
|||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|
||||||
init();
|
init();
|
||||||
this->setWindowTitle(tr("UEFITool %1 - %2").arg(version).arg(fileInfo.fileName()));
|
setWindowTitle(tr("UEFITool %1 - %2").arg(version).arg(fileInfo.fileName()));
|
||||||
|
|
||||||
UINT8 result = ffsParser->parseImageFile(buffer, model->index(0,0));
|
UINT8 result = ffsParser->parseImageFile(buffer, model->index(0,0));
|
||||||
showParserMessages();
|
showParserMessages();
|
||||||
|
@ -11,3 +11,262 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "ffsbuilder.h"
|
||||||
|
|
||||||
|
FfsBuilder::FfsBuilder(const TreeModel* treeModel, QObject *parent)
|
||||||
|
: QObject(parent), model(treeModel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FfsBuilder::~FfsBuilder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FfsBuilder::msg(const QString & message, const QModelIndex & index)
|
||||||
|
{
|
||||||
|
messagesVector.push_back(QPair<QString, QModelIndex>(message, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPair<QString, QModelIndex> > FfsBuilder::getMessages() const
|
||||||
|
{
|
||||||
|
return messagesVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FfsBuilder::clearMessages()
|
||||||
|
{
|
||||||
|
messagesVector.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::build(const QModelIndex & root, QByteArray & image)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
STATUS result;
|
||||||
|
|
||||||
|
// No action required
|
||||||
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
capsule = model->header(index).append(model->body(index));
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild or Replace
|
||||||
|
else if (model->action(index) == Actions::Rebuild
|
||||||
|
|| model->action(index) == Actions::Replace) {
|
||||||
|
if (model->rowCount(index)) {
|
||||||
|
// Clear the supplied QByteArray
|
||||||
|
capsule.clear();
|
||||||
|
|
||||||
|
// Reconstruct children
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
QModelIndex currentChild = index.child(i, 0);
|
||||||
|
QByteArray currentData;
|
||||||
|
// Check child type
|
||||||
|
if (model->type(currentChild) == Types::Image) {
|
||||||
|
result = buildImage(currentChild, currentData);
|
||||||
|
if (!result) {
|
||||||
|
capsule.append(currentData);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg(tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||||
|
capsule.append(model->header(currentChild)).append(model->body(currentChild));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg(tr("buildCapsule: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(currentChild))), currentChild);
|
||||||
|
capsule.append(model->header(currentChild)).append(model->body(currentChild));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check size of reconstructed capsule, it must remain the same
|
||||||
|
if (capsule.size() > model->body(index).size()) {
|
||||||
|
msg(tr("buildCapsule: new capsule size %1h (%2) is bigger than the original %3h (%4)")
|
||||||
|
.hexarg(capsule.size()).arg(capsule.size())
|
||||||
|
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||||
|
index);
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else if (capsule.size() < model->body(index).size()) {
|
||||||
|
msg(tr("buildCapsule: new capsule size %1h (%2) is smaller than the original %3h (%4)")
|
||||||
|
.hexarg(capsule.size()).arg(capsule.size())
|
||||||
|
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||||
|
index);
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
capsule = model->body(index);
|
||||||
|
|
||||||
|
// Build successful, append header
|
||||||
|
capsule = model->header(index).append(capsule);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
msg(tr("buildCapsule: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildImage(const QModelIndex & index, QByteArray & intelImage)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildRawArea(const QModelIndex & index, QByteArray & rawArea)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
STATUS result;
|
||||||
|
|
||||||
|
// No action required
|
||||||
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
rawArea = model->header(index).append(model->body(index));
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild or Replace
|
||||||
|
else if (model->action(index) == Actions::Rebuild
|
||||||
|
|| model->action(index) == Actions::Replace) {
|
||||||
|
if (model->rowCount(index)) {
|
||||||
|
// Clear the supplied QByteArray
|
||||||
|
rawArea.clear();
|
||||||
|
|
||||||
|
// Reconstruct children
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
QModelIndex currentChild = index.child(i, 0);
|
||||||
|
QByteArray currentData;
|
||||||
|
// Check child type
|
||||||
|
if (model->type(currentChild) == Types::Volume) {
|
||||||
|
result = buildVolume(currentChild, currentData);
|
||||||
|
}
|
||||||
|
else if (model->type(currentChild) == Types::Padding) {
|
||||||
|
result = buildPadding(currentChild, currentData);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg(tr("buildRawArea: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(currentChild))), currentChild);
|
||||||
|
result = ERR_SUCCESS;
|
||||||
|
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||||
|
}
|
||||||
|
// Check build result
|
||||||
|
if (result) {
|
||||||
|
msg(tr("buildRawArea: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
||||||
|
currentData = model->header(currentChild).append(model->body(currentChild));
|
||||||
|
}
|
||||||
|
// Append current data
|
||||||
|
rawArea.append(currentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check size of reconstructed raw area, it must remain the same
|
||||||
|
if (rawArea.size() > model->body(index).size()) {
|
||||||
|
msg(tr("buildRawArea: new raw area size %1h (%2) is bigger than the original %3h (%4)")
|
||||||
|
.hexarg(rawArea.size()).arg(rawArea.size())
|
||||||
|
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||||
|
index);
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
else if (rawArea.size() < model->body(index).size()) {
|
||||||
|
msg(tr("buildRawArea: new raw area size %1h (%2) is smaller than the original %3h (%4)")
|
||||||
|
.hexarg(rawArea.size()).arg(rawArea.size())
|
||||||
|
.hexarg(model->body(index).size()).arg(model->body(index).size()),
|
||||||
|
index);
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rawArea = model->body(index);
|
||||||
|
|
||||||
|
// Build successful, append header
|
||||||
|
rawArea = model->header(index).append(rawArea);
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(tr("buildRawArea: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildVolume(const QModelIndex & index, QByteArray & volume)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildPadding(const QModelIndex & index, QByteArray & padding)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// No action required
|
||||||
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
padding = model->header(index).append(model->body(index));
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase
|
||||||
|
else if (model->action(index) == Actions::Erase) {
|
||||||
|
padding.fill('\xFF', model->header(index).size() + model->body(index).size());
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(tr("buildPadding: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildNonUefiData(const QModelIndex & index, QByteArray & data)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// No action required
|
||||||
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
data = model->header(index).append(model->body(index));
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase
|
||||||
|
else if (model->action(index) == Actions::Erase) {
|
||||||
|
data.fill('\xFF', model->header(index).size() + model->body(index).size());
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(tr("buildNonUefiData: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildFreeSpace(const QModelIndex & index, QByteArray & freeSpace)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// No action required
|
||||||
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
freeSpace = model->header(index).append(model->body(index));
|
||||||
|
return ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg(tr("buildFreeSpace: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildPadFile(const QModelIndex & index, QByteArray & padFile)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildFile(const QModelIndex & index, QByteArray & file)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATUS FfsBuilder::buildSection(const QModelIndex & index, QByteArray & section)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -14,4 +14,47 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#ifndef __FFSBUILDER_H__
|
#ifndef __FFSBUILDER_H__
|
||||||
#define __FFSBUILDER_H__
|
#define __FFSBUILDER_H__
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
#include "../common/basetypes.h"
|
||||||
|
#include "../common/treemodel.h"
|
||||||
|
#include "../common/ffs.h"
|
||||||
|
#include "../common/utility.h"
|
||||||
|
|
||||||
|
class FfsBuilder : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FfsBuilder(const TreeModel * treeModel, QObject *parent = 0);
|
||||||
|
~FfsBuilder();
|
||||||
|
|
||||||
|
QVector<QPair<QString, QModelIndex> > getMessages() const;
|
||||||
|
void clearMessages();
|
||||||
|
|
||||||
|
STATUS build(const QModelIndex & root, QByteArray & image);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TreeModel* model;
|
||||||
|
QVector<QPair<QString, QModelIndex> > messagesVector;
|
||||||
|
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||||
|
|
||||||
|
// UEFI standard structures
|
||||||
|
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
|
||||||
|
STATUS buildImage(const QModelIndex & index, QByteArray & intelImage);
|
||||||
|
STATUS buildRegion(const QModelIndex & index, QByteArray & region);
|
||||||
|
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea);
|
||||||
|
STATUS buildVolume(const QModelIndex & index, QByteArray & volume);
|
||||||
|
STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
|
||||||
|
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);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,11 +84,11 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
.hexarg2(capsuleHeader->Flags, 8);
|
.hexarg2(capsuleHeader->Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = getParsingData(QModelIndex());
|
PARSING_DATA pdata = parsingDataFromQByteArray(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, convertParsingData(pdata), root);
|
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||||
}
|
}
|
||||||
// Check buffer for being extended Aptio signed capsule header
|
// Check buffer for being extended Aptio signed capsule header
|
||||||
else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) {
|
else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) {
|
||||||
@ -107,11 +107,11 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = getParsingData(QModelIndex());
|
PARSING_DATA pdata = parsingDataFromQByteArray(QModelIndex());
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, convertParsingData(pdata), root);
|
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
||||||
|
|
||||||
// Show message about possible Aptio signature break
|
// Show message about possible Aptio signature break
|
||||||
if (signedCapsule) {
|
if (signedCapsule) {
|
||||||
@ -145,12 +145,12 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
.hexarg(capsuleHeaderSize).hexarg(flashImage.size()).arg(flashImage.size());
|
.hexarg(capsuleHeaderSize).hexarg(flashImage.size()).arg(flashImage.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
pdata.fixed = TRUE;
|
pdata.fixed = TRUE;
|
||||||
pdata.offset = capsuleHeaderSize;
|
pdata.offset = capsuleHeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, convertParsingData(pdata), index);
|
QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Parse the image
|
// Parse the image
|
||||||
return parseRawArea(flashImage, biosIndex);
|
return parseRawArea(flashImage, biosIndex);
|
||||||
@ -163,7 +163,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelInd
|
|||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Store the beginning of descriptor as descriptor base address
|
// Store the beginning of descriptor as descriptor base address
|
||||||
const UINT8* descriptor = (const UINT8*)intelImage.constData();
|
const UINT8* descriptor = (const UINT8*)intelImage.constData();
|
||||||
@ -297,7 +297,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelInd
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add Intel image tree item
|
// Add Intel image tree item
|
||||||
index = model->addItem(Types::Image, Subtypes::IntelImage, name, QString(), info, QByteArray(), intelImage, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Image, Subtypes::IntelImage, name, QString(), info, QByteArray(), intelImage, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Descriptor
|
// Descriptor
|
||||||
// Get descriptor info
|
// Get descriptor info
|
||||||
@ -365,7 +365,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelInd
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add descriptor tree item
|
// Add descriptor tree item
|
||||||
model->addItem(Types::Region, Subtypes::DescriptorRegion, name, QString(), info, QByteArray(), body, convertParsingData(pdata), index);
|
model->addItem(Types::Region, Subtypes::DescriptorRegion, name, QString(), info, QByteArray(), body, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Sort regions in ascending order
|
// Sort regions in ascending order
|
||||||
qSort(offsets);
|
qSort(offsets);
|
||||||
@ -407,7 +407,7 @@ STATUS FfsParser::parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffs
|
|||||||
return ERR_EMPTY_REGION;
|
return ERR_EMPTY_REGION;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("GbE region");
|
QString name = tr("GbE region");
|
||||||
@ -430,7 +430,7 @@ STATUS FfsParser::parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffs
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::GbeRegion, name, QString(), info, QByteArray(), gbe, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::GbeRegion, name, QString(), info, QByteArray(), gbe, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -442,7 +442,7 @@ STATUS FfsParser::parseMeRegion(const QByteArray & me, const UINT32 parentOffset
|
|||||||
return ERR_EMPTY_REGION;
|
return ERR_EMPTY_REGION;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("ME region");
|
QString name = tr("ME region");
|
||||||
@ -487,7 +487,7 @@ STATUS FfsParser::parseMeRegion(const QByteArray & me, const UINT32 parentOffset
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::MeRegion, name, QString(), info, QByteArray(), me, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::MeRegion, name, QString(), info, QByteArray(), me, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (emptyRegion) {
|
if (emptyRegion) {
|
||||||
@ -507,7 +507,7 @@ STATUS FfsParser::parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffs
|
|||||||
return ERR_EMPTY_REGION;
|
return ERR_EMPTY_REGION;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("PDR region");
|
QString name = tr("PDR region");
|
||||||
@ -520,7 +520,7 @@ STATUS FfsParser::parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffs
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::PdrRegion, name, QString(), info, QByteArray(), pdr, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::PdrRegion, name, QString(), info, QByteArray(), pdr, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Parse PDR region as BIOS space
|
// Parse PDR region as BIOS space
|
||||||
UINT8 result = parseRawArea(pdr, index);
|
UINT8 result = parseRawArea(pdr, index);
|
||||||
@ -537,7 +537,7 @@ STATUS FfsParser::parseBiosRegion(const QByteArray & bios, const UINT32 parentOf
|
|||||||
return ERR_EMPTY_REGION;
|
return ERR_EMPTY_REGION;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("BIOS region");
|
QString name = tr("BIOS region");
|
||||||
@ -550,7 +550,7 @@ STATUS FfsParser::parseBiosRegion(const QByteArray & bios, const UINT32 parentOf
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::BiosRegion, name, QString(), info, QByteArray(), bios, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::BiosRegion, name, QString(), info, QByteArray(), bios, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return parseRawArea(bios, index);
|
return parseRawArea(bios, index);
|
||||||
}
|
}
|
||||||
@ -571,7 +571,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get parsing data
|
// Get parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
UINT32 offset = pdata.offset;
|
UINT32 offset = pdata.offset;
|
||||||
UINT32 headerSize = model->header(index).size();
|
UINT32 headerSize = model->header(index).size();
|
||||||
|
|
||||||
@ -598,7 +598,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, convertParsingData(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for and parse all volumes
|
// Search for and parse all volumes
|
||||||
@ -624,7 +624,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, convertParsingData(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get volume size
|
// Get volume size
|
||||||
@ -651,7 +651,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, convertParsingData(pdata), index);
|
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
msg(tr("parseRawArea: one of volumes inside overlaps the end of data"), paddingIndex);
|
msg(tr("parseRawArea: one of volumes inside overlaps the end of data"), paddingIndex);
|
||||||
|
|
||||||
// Update variables
|
// Update variables
|
||||||
@ -696,7 +696,7 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, convertParsingData(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse bodies
|
//Parse bodies
|
||||||
@ -724,7 +724,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Populate volume header
|
// Populate volume header
|
||||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData());
|
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData());
|
||||||
@ -882,7 +882,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
else if (ffsVersion == 3)
|
else if (ffsVersion == 3)
|
||||||
subtype = Subtypes::Ffs3Volume;
|
subtype = Subtypes::Ffs3Volume;
|
||||||
}
|
}
|
||||||
index = model->addItem(Types::Volume, subtype, name, text, info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Volume, subtype, name, text, info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (isUnknown)
|
if (isUnknown)
|
||||||
@ -945,7 +945,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
UINT32 volumeHeaderSize = model->header(index).size();
|
UINT32 volumeHeaderSize = model->header(index).size();
|
||||||
|
|
||||||
// Get parsing data
|
// Get parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
UINT32 offset = pdata.offset;
|
UINT32 offset = pdata.offset;
|
||||||
|
|
||||||
if (pdata.ffsVersion != 2 && pdata.ffsVersion != 3) // Don't parse unknown volumes
|
if (pdata.ffsVersion != 2 && pdata.ffsVersion != 3) // Don't parse unknown volumes
|
||||||
@ -992,7 +992,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add free space item
|
// Add free space item
|
||||||
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), free, convertParsingData(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), free, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
// ... and all bytes after as a padding
|
// ... and all bytes after as a padding
|
||||||
pdata.fixed = TRUE; // Non-UEFI data is fixed
|
pdata.fixed = TRUE; // Non-UEFI data is fixed
|
||||||
@ -1004,7 +1004,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add padding tree item
|
// Add padding tree item
|
||||||
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, convertParsingData(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
msg(tr("parseVolumeBody: non-UEFI data found in volume's free space"), dataIndex);
|
msg(tr("parseVolumeBody: non-UEFI data found in volume's free space"), dataIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1017,7 +1017,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add free space item
|
// Add free space item
|
||||||
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), freeSpace, convertParsingData(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), freeSpace, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
break; // Exit from parsing loop
|
break; // Exit from parsing loop
|
||||||
}
|
}
|
||||||
@ -1032,7 +1032,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add padding tree item
|
// Add padding tree item
|
||||||
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, convertParsingData(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Show message
|
// Show message
|
||||||
msg(tr("parseVolumeBody: non-UEFI data found inside volume's file space"), dataIndex);
|
msg(tr("parseVolumeBody: non-UEFI data found inside volume's file space"), dataIndex);
|
||||||
@ -1124,7 +1124,7 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get parent's parsing data
|
// Get parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Get file header
|
// Get file header
|
||||||
QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER));
|
QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER));
|
||||||
@ -1224,7 +1224,7 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::File, fileHeader->Type, name, "", info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::File, fileHeader->Type, name, "", info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (msgUnalignedFile)
|
if (msgUnalignedFile)
|
||||||
@ -1290,7 +1290,7 @@ STATUS FfsParser::parsePadFileBody(const QModelIndex & index)
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get data from parsing data
|
// Get data from parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
|
|
||||||
// Check if all bytes of the file are empty
|
// Check if all bytes of the file are empty
|
||||||
QByteArray body = model->body(index);
|
QByteArray body = model->body(index);
|
||||||
@ -1322,7 +1322,7 @@ STATUS FfsParser::parsePadFileBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::FreeSpace, 0, tr("Free space"), QString(), info, QByteArray(), free, convertParsingData(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Free space"), QString(), info, QByteArray(), free, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1339,7 +1339,7 @@ STATUS FfsParser::parsePadFileBody(const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, convertParsingData(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Show message
|
// Show message
|
||||||
msg(tr("parsePadFileBody: non-UEFI data found in pad-file"), dataIndex);
|
msg(tr("parsePadFileBody: non-UEFI data found in pad-file"), dataIndex);
|
||||||
@ -1357,7 +1357,7 @@ STATUS FfsParser::parseSections(QByteArray sections, const QModelIndex & index)
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get data from parsing data
|
// Get data from parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
|
|
||||||
// Search for and parse all sections
|
// Search for and parse all sections
|
||||||
UINT32 bodySize = sections.size();
|
UINT32 bodySize = sections.size();
|
||||||
@ -1381,7 +1381,7 @@ STATUS FfsParser::parseSections(QByteArray sections, const QModelIndex & index)
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, convertParsingData(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Show message
|
// Show message
|
||||||
msg(tr("parseSections: non-UEFI data found in sections area"), dataIndex);
|
msg(tr("parseSections: non-UEFI data found in sections area"), dataIndex);
|
||||||
@ -1453,7 +1453,7 @@ STATUS FfsParser::parseSectionHeader(const QByteArray & section, const UINT32 pa
|
|||||||
STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1477,7 +1477,7 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1485,7 +1485,7 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1520,7 +1520,7 @@ STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1528,7 +1528,7 @@ STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const
|
|||||||
STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1564,7 +1564,7 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1572,7 +1572,7 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1640,7 +1640,7 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (msgSigned)
|
if (msgSigned)
|
||||||
@ -1659,7 +1659,7 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
|
|||||||
STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1689,7 +1689,7 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1697,7 +1697,7 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
|
|||||||
STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||||
{
|
{
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = getParsingData(parent);
|
PARSING_DATA pdata = parsingDataFromQByteArray(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
@ -1727,7 +1727,7 @@ STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const U
|
|||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, convertParsingData(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1773,7 +1773,7 @@ STATUS FfsParser::parseCompressedSectionBody(const QModelIndex & index)
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get data from parsing data
|
// Get data from parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
UINT8 algorithm = pdata.section.compressed.compressionType;
|
UINT8 algorithm = pdata.section.compressed.compressionType;
|
||||||
|
|
||||||
// Decompress section
|
// Decompress section
|
||||||
@ -1800,7 +1800,7 @@ STATUS FfsParser::parseCompressedSectionBody(const QModelIndex & index)
|
|||||||
// Update parsing data
|
// Update parsing data
|
||||||
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
||||||
pdata.section.compressed.algorithm = algorithm;
|
pdata.section.compressed.algorithm = algorithm;
|
||||||
model->setParsingData(index, convertParsingData(pdata));
|
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
||||||
|
|
||||||
// Parse decompressed data
|
// Parse decompressed data
|
||||||
return parseSections(decompressed, index);
|
return parseSections(decompressed, index);
|
||||||
@ -1813,7 +1813,7 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
|
|||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get data from parsing data
|
// Get data from parsing data
|
||||||
PARSING_DATA pdata = getParsingData(index);
|
PARSING_DATA pdata = parsingDataFromQByteArray(index);
|
||||||
UINT32 attributes = pdata.section.guidDefined.attributes;
|
UINT32 attributes = pdata.section.guidDefined.attributes;
|
||||||
EFI_GUID guid = pdata.section.guidDefined.guid;
|
EFI_GUID guid = pdata.section.guidDefined.guid;
|
||||||
|
|
||||||
@ -1895,7 +1895,7 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
|
|||||||
|
|
||||||
// Update parsing data
|
// Update parsing data
|
||||||
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
||||||
model->setParsingData(index, convertParsingData(pdata));
|
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
||||||
|
|
||||||
if (!parseCurrentSection) {
|
if (!parseCurrentSection) {
|
||||||
msg(tr("parseGuidedSectionBody: GUID defined section can not be processed"), index);
|
msg(tr("parseGuidedSectionBody: GUID defined section can not be processed"), index);
|
||||||
|
@ -17,14 +17,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
QString machineTypeToQString(UINT16 machineType)
|
QString machineTypeToQString(UINT16 machineType)
|
||||||
{
|
{
|
||||||
switch (machineType){
|
switch (machineType) {
|
||||||
case IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
|
case EFI_IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
|
||||||
case IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
|
case EFI_IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
|
||||||
case IMAGE_FILE_MACHINE_ARMV7: return QObject::tr("ARMv7");
|
case EFI_IMAGE_FILE_MACHINE_ARMNT: return QObject::tr("ARMv7");
|
||||||
case IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
|
case EFI_IMAGE_FILE_MACHINE_ARM64: return QObject::tr("ARM64");
|
||||||
case IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
|
case EFI_IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
|
||||||
case IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
|
case EFI_IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
|
||||||
case IMAGE_FILE_MACHINE_THUMB: return QObject::tr("Thumb");
|
case EFI_IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
|
||||||
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
|
case EFI_IMAGE_FILE_MACHINE_POWERPC: return QObject::tr("PowerPC");
|
||||||
|
case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return QObject::tr("PowerPC FP");
|
||||||
|
case EFI_IMAGE_FILE_MACHINE_THUMB: return QObject::tr("Thumb");
|
||||||
|
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,13 +36,16 @@ extern QString machineTypeToQString(UINT16 machineType);
|
|||||||
//
|
//
|
||||||
// PE32+ Machine type for EFI images
|
// PE32+ Machine type for EFI images
|
||||||
//
|
//
|
||||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
#define EFI_IMAGE_FILE_MACHINE_I386 0x014c // x86
|
||||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
#define EFI_IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little endian
|
||||||
#define IMAGE_FILE_MACHINE_ARMV7 0x01c4
|
#define EFI_IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM or Thumb (interworking)
|
||||||
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
|
#define EFI_IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARMv7 (or higher) Thumb mode only
|
||||||
#define IMAGE_FILE_MACHINE_I386 0x014c
|
#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x01f0 // Power PC little endian
|
||||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
#define EFI_IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 // Power PC with floating point support
|
||||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
#define EFI_IMAGE_FILE_MACHINE_IA64 0x0200 // Itanium
|
||||||
|
#define EFI_IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI Byte Code
|
||||||
|
#define EFI_IMAGE_FILE_MACHINE_AMD64 0x8664 // x86-64
|
||||||
|
#define EFI_IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARMv8 in 64-bit mode
|
||||||
|
|
||||||
//
|
//
|
||||||
// EXE file formats
|
// EXE file formats
|
||||||
@ -438,25 +441,25 @@ typedef struct {
|
|||||||
#define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address
|
#define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address
|
||||||
|
|
||||||
//
|
//
|
||||||
// x64 processor relocation types.
|
// x64 processor relocation types
|
||||||
//
|
//
|
||||||
#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
|
#define EFI_IMAGE_REL_AMD64_ABSOLUTE 0x0000
|
||||||
#define IMAGE_REL_AMD64_ADDR64 0x0001
|
#define EFI_IMAGE_REL_AMD64_ADDR64 0x0001
|
||||||
#define IMAGE_REL_AMD64_ADDR32 0x0002
|
#define EFI_IMAGE_REL_AMD64_ADDR32 0x0002
|
||||||
#define IMAGE_REL_AMD64_ADDR32NB 0x0003
|
#define EFI_IMAGE_REL_AMD64_ADDR32NB 0x0003
|
||||||
#define IMAGE_REL_AMD64_REL32 0x0004
|
#define EFI_IMAGE_REL_AMD64_REL32 0x0004
|
||||||
#define IMAGE_REL_AMD64_REL32_1 0x0005
|
#define EFI_IMAGE_REL_AMD64_REL32_1 0x0005
|
||||||
#define IMAGE_REL_AMD64_REL32_2 0x0006
|
#define EFI_IMAGE_REL_AMD64_REL32_2 0x0006
|
||||||
#define IMAGE_REL_AMD64_REL32_3 0x0007
|
#define EFI_IMAGE_REL_AMD64_REL32_3 0x0007
|
||||||
#define IMAGE_REL_AMD64_REL32_4 0x0008
|
#define EFI_IMAGE_REL_AMD64_REL32_4 0x0008
|
||||||
#define IMAGE_REL_AMD64_REL32_5 0x0009
|
#define EFI_IMAGE_REL_AMD64_REL32_5 0x0009
|
||||||
#define IMAGE_REL_AMD64_SECTION 0x000A
|
#define EFI_IMAGE_REL_AMD64_SECTION 0x000A
|
||||||
#define IMAGE_REL_AMD64_SECREL 0x000B
|
#define EFI_IMAGE_REL_AMD64_SECREL 0x000B
|
||||||
#define IMAGE_REL_AMD64_SECREL7 0x000C
|
#define EFI_IMAGE_REL_AMD64_SECREL7 0x000C
|
||||||
#define IMAGE_REL_AMD64_TOKEN 0x000D
|
#define EFI_IMAGE_REL_AMD64_TOKEN 0x000D
|
||||||
#define IMAGE_REL_AMD64_SREL32 0x000E
|
#define EFI_IMAGE_REL_AMD64_SREL32 0x000E
|
||||||
#define IMAGE_REL_AMD64_PAIR 0x000F
|
#define EFI_IMAGE_REL_AMD64_PAIR 0x000F
|
||||||
#define IMAGE_REL_AMD64_SSPAN32 0x0010
|
#define EFI_IMAGE_REL_AMD64_SSPAN32 0x0010
|
||||||
|
|
||||||
//
|
//
|
||||||
// Based relocation format
|
// Based relocation format
|
||||||
|
@ -21,6 +21,7 @@ namespace Actions
|
|||||||
{
|
{
|
||||||
enum ActionTypes {
|
enum ActionTypes {
|
||||||
NoAction = 50,
|
NoAction = 50,
|
||||||
|
Erase,
|
||||||
Create,
|
Create,
|
||||||
Insert,
|
Insert,
|
||||||
Replace,
|
Replace,
|
||||||
|
@ -20,7 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "LZMA/LzmaDecompress.h"
|
#include "LZMA/LzmaDecompress.h"
|
||||||
|
|
||||||
// Returns either new parsing data instance or obtains it from index
|
// Returns either new parsing data instance or obtains it from index
|
||||||
PARSING_DATA getParsingData(const QModelIndex & index)
|
PARSING_DATA parsingDataFromQByteArray(const QModelIndex & index)
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
TreeModel* model = (TreeModel*)index.model();
|
TreeModel* model = (TreeModel*)index.model();
|
||||||
@ -39,7 +39,7 @@ PARSING_DATA getParsingData(const QModelIndex & index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts parsing data to byte array
|
// Converts parsing data to byte array
|
||||||
QByteArray convertParsingData(const PARSING_DATA & pdata)
|
QByteArray parsingDataToQByteArray(const PARSING_DATA & pdata)
|
||||||
{
|
{
|
||||||
return QByteArray((const char*)&pdata, sizeof(PARSING_DATA));
|
return QByteArray((const char*)&pdata, sizeof(PARSING_DATA));
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "parsingdata.h"
|
#include "parsingdata.h"
|
||||||
|
|
||||||
// Returns either new parsing data instance or obtains it from index
|
// Returns either new parsing data instance or obtains it from index
|
||||||
PARSING_DATA getParsingData(const QModelIndex & index);
|
PARSING_DATA parsingDataFromQByteArray(const QModelIndex & index);
|
||||||
|
|
||||||
// Converts parsing data to byte array
|
// Converts parsing data to byte array
|
||||||
QByteArray convertParsingData(const PARSING_DATA & pdata);
|
QByteArray parsingDataToQByteArray(const PARSING_DATA & pdata);
|
||||||
|
|
||||||
// Converts error code to QString
|
// Converts error code to QString
|
||||||
extern QString errorCodeToQString(UINT8 errorCode);
|
extern QString errorCodeToQString(UINT8 errorCode);
|
||||||
|
Loading…
Reference in New Issue
Block a user