mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 17:38:22 +08:00
UT NE A17
- nothing major, just reworks and preparations for the new rebuild code - added try / catch bad_alloc to prevent crashes during decompression of malformed Tiano/EFI11 compressed data
This commit is contained in:
parent
d1add47500
commit
a1253050fe
@ -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_alpha16"))
|
version(tr("0.30.0_alpha17"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
|
@ -32,44 +32,76 @@ Providing both EFI and Tiano decompress algorithms.
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 CompSize;
|
UINT32 CompSize;
|
||||||
UINT32 OrigSize;
|
UINT32 OrigSize;
|
||||||
} EFI_TIANO_HEADER;
|
} EFI_TIANO_HEADER;
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EfiTianoGetInfo(
|
EfiTianoGetInfo(
|
||||||
const VOID *Source,
|
const VOID *Source,
|
||||||
UINT32 SrcSize,
|
UINT32 SrcSize,
|
||||||
UINT32 *DstSize,
|
UINT32 *DstSize,
|
||||||
UINT32 *ScratchSize
|
UINT32 *ScratchSize
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.GetInfo().
|
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.GetInfo().
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
This - The protocol instance pointer
|
Source - The source buffer containing the compressed data.
|
||||||
Source - The source buffer containing the compressed data.
|
SrcSize - The size of source buffer
|
||||||
SrcSize - The size of source buffer
|
DstSize - The size of destination buffer.
|
||||||
DstSize - The size of destination buffer.
|
ScratchSize - The size of scratch buffer.
|
||||||
ScratchSize - The size of scratch buffer.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
|
EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
|
||||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
;
|
;
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EfiDecompress(
|
EfiDecompress(
|
||||||
|
const VOID *Source,
|
||||||
|
UINT32 SrcSize,
|
||||||
|
VOID *Destination,
|
||||||
|
UINT32 DstSize,
|
||||||
|
VOID *Scratch,
|
||||||
|
UINT32 ScratchSize
|
||||||
|
);
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Source - The source buffer containing the compressed data.
|
||||||
|
SrcSize - The size of source buffer
|
||||||
|
Destination - The destination buffer to store the decompressed data
|
||||||
|
DstSize - The size of destination buffer.
|
||||||
|
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||||
|
ScratchSize - The size of scratch buffer.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
EFI_SUCCESS - Decompression is successful
|
||||||
|
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
TianoDecompress(
|
||||||
const VOID *Source,
|
const VOID *Source,
|
||||||
UINT32 SrcSize,
|
UINT32 SrcSize,
|
||||||
VOID *Destination,
|
VOID *Destination,
|
||||||
@ -77,63 +109,28 @@ extern "C" {
|
|||||||
VOID *Scratch,
|
VOID *Scratch,
|
||||||
UINT32 ScratchSize
|
UINT32 ScratchSize
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
The implementation is same as that of EFI_DECOMPRESS_PROTOCOL.Decompress().
|
The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
This - The protocol instance pointer
|
Source - The source buffer containing the compressed data.
|
||||||
Source - The source buffer containing the compressed data.
|
SrcSize - The size of source buffer
|
||||||
SrcSize - The size of source buffer
|
Destination - The destination buffer to store the decompressed data
|
||||||
Destination - The destination buffer to store the decompressed data
|
DstSize - The size of destination buffer.
|
||||||
DstSize - The size of destination buffer.
|
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
ScratchSize - The size of scratch buffer.
|
||||||
ScratchSize - The size of scratch buffer.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
EFI_SUCCESS - Decompression is successful
|
EFI_SUCCESS - Decompression is successful
|
||||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
EFI_INVALID_PARAMETER - The source data is corrupted
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
;
|
;
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
TianoDecompress(
|
|
||||||
const VOID *Source,
|
|
||||||
UINT32 SrcSize,
|
|
||||||
VOID *Destination,
|
|
||||||
UINT32 DstSize,
|
|
||||||
VOID *Scratch,
|
|
||||||
UINT32 ScratchSize
|
|
||||||
)
|
|
||||||
/*++
|
|
||||||
|
|
||||||
Routine Description:
|
|
||||||
|
|
||||||
The implementation is same as that of EFI_TIANO_DECOMPRESS_PROTOCOL.Decompress().
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
This - The protocol instance pointer
|
|
||||||
Source - The source buffer containing the compressed data.
|
|
||||||
SrcSize - The size of source buffer
|
|
||||||
Destination - The destination buffer to store the decompressed data
|
|
||||||
DstSize - The size of destination buffer.
|
|
||||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
|
||||||
ScratchSize - The size of scratch buffer.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
EFI_SUCCESS - Decompression is successful
|
|
||||||
EFI_INVALID_PARAMETER - The source data is corrupted
|
|
||||||
|
|
||||||
--*/
|
|
||||||
;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,9 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
STATUS result;
|
|
||||||
|
|
||||||
// No action required
|
// No action required
|
||||||
if (model->action(index) == Actions::NoAction) {
|
if (model->action(index) == Actions::NoAction) {
|
||||||
|
// Use original item data
|
||||||
capsule = model->header(index).append(model->body(index));
|
capsule = model->header(index).append(model->body(index));
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -69,41 +68,49 @@ STATUS FfsBuilder::buildCapsule(const QModelIndex & index, QByteArray & capsule)
|
|||||||
// Clear the supplied QByteArray
|
// Clear the supplied QByteArray
|
||||||
capsule.clear();
|
capsule.clear();
|
||||||
|
|
||||||
// Build children
|
// Right now there is only one capsule image element supported
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
if (model->rowCount(index) != 1) {
|
||||||
QModelIndex currentChild = index.child(i, 0);
|
msg(tr("buildCapsule: building of capsules with %1 elements are not supported, original item data used").arg(model->rowCount(index)), index);
|
||||||
QByteArray currentData;
|
// Use original item data
|
||||||
// Check child type
|
capsule = model->header(index).append(model->body(index));
|
||||||
if (model->type(currentChild) == Types::Image) {
|
return ERR_SUCCESS;
|
||||||
if (model->subtype(currentChild) == Subtypes::IntelImage)
|
}
|
||||||
result = buildIntelImage(currentChild, currentData);
|
|
||||||
|
// Build image
|
||||||
|
QModelIndex imageIndex = index.child(0, 0);
|
||||||
|
QByteArray imageData;
|
||||||
|
|
||||||
|
// Check image type
|
||||||
|
if (model->type(imageIndex) == Types::Image) {
|
||||||
|
STATUS result;
|
||||||
|
if (model->subtype(imageIndex) == Subtypes::IntelImage)
|
||||||
|
result = buildIntelImage(imageIndex, imageData);
|
||||||
else
|
else
|
||||||
result = buildRawArea(currentChild, currentData);
|
result = buildRawArea(imageIndex, imageData);
|
||||||
|
|
||||||
// Check build result
|
// Check build result
|
||||||
if (result) {
|
if (result) {
|
||||||
msg(tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(currentChild)).arg(errorCodeToQString(result)), currentChild);
|
msg(tr("buildCapsule: building of \"%1\" failed with error \"%2\", original item data used").arg(model->name(imageIndex)).arg(errorCodeToQString(result)), imageIndex);
|
||||||
capsule.append(model->header(currentChild)).append(model->body(currentChild));
|
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
capsule.append(currentData);
|
capsule.append(imageData);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg(tr("buildCapsule: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(currentChild))), currentChild);
|
msg(tr("buildCapsule: unexpected child item of type \"%1\" can't be processed, original item data used").arg(itemTypeToQString(model->type(imageIndex))), imageIndex);
|
||||||
capsule.append(model->header(currentChild)).append(model->body(currentChild));
|
capsule.append(model->header(imageIndex)).append(model->body(imageIndex));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check size of reconstructed capsule, it must remain the same
|
// Check size of reconstructed capsule, it must remain the same
|
||||||
UINT32 newSize = capsule.size();
|
UINT32 newSize = capsule.size();
|
||||||
UINT32 oldSize = model->body(index).size();
|
UINT32 oldSize = model->body(index).size();
|
||||||
if (newSize > oldSize) {
|
if (newSize > oldSize) {
|
||||||
msg(tr("buildCapsule: new capsule size %1h (%2) is bigger than the original %3h (%4)")
|
msg(tr("buildCapsule: new capsule body size %1h (%2) is bigger than the original %3h (%4)")
|
||||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
|
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize),index);
|
||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
else if (newSize < oldSize) {
|
else if (newSize < oldSize) {
|
||||||
msg(tr("buildCapsule: new capsule size %1h (%2) is smaller than the original %3h (%4)")
|
msg(tr("buildCapsule: new capsule body size %1h (%2) is smaller than the original %3h (%4)")
|
||||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
@ -125,7 +132,7 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
|
||||||
UINT8 result;
|
|
||||||
|
|
||||||
// No action
|
// No action
|
||||||
if (model->action(index) == Actions::NoAction) {
|
if (model->action(index) == Actions::NoAction) {
|
||||||
@ -136,75 +143,94 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
|||||||
// Other supported actions
|
// Other supported actions
|
||||||
else if (model->action(index) == Actions::Rebuild) {
|
else if (model->action(index) == Actions::Rebuild) {
|
||||||
intelImage.clear();
|
intelImage.clear();
|
||||||
// First child will always be descriptor for this type of image
|
// First child will always be descriptor for this type of image, and it's read only
|
||||||
QByteArray descriptor;
|
QByteArray descriptor = model->header(index.child(0, 0)).append(model->body(index.child(0, 0)));
|
||||||
result = buildRegion(index.child(0, 0), descriptor);
|
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
intelImage.append(descriptor);
|
|
||||||
|
|
||||||
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor.constData() + sizeof(FLASH_DESCRIPTOR_HEADER));
|
// Other regions can be in different order, GbE, PDR and EC my be skipped
|
||||||
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->RegionBase);
|
|
||||||
QByteArray gbe;
|
QByteArray gbe;
|
||||||
UINT32 gbeBegin = calculateRegionOffset(regionSection->GbeBase);
|
|
||||||
UINT32 gbeEnd = gbeBegin + calculateRegionSize(regionSection->GbeBase, regionSection->GbeLimit);
|
|
||||||
QByteArray me;
|
QByteArray me;
|
||||||
UINT32 meBegin = calculateRegionOffset(regionSection->MeBase);
|
|
||||||
UINT32 meEnd = meBegin + calculateRegionSize(regionSection->MeBase, regionSection->MeLimit);
|
|
||||||
QByteArray bios;
|
QByteArray bios;
|
||||||
UINT32 biosBegin = calculateRegionOffset(regionSection->BiosBase);
|
|
||||||
UINT32 biosEnd = biosBegin + calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit);
|
|
||||||
QByteArray pdr;
|
QByteArray pdr;
|
||||||
UINT32 pdrBegin = calculateRegionOffset(regionSection->PdrBase);
|
QByteArray ec;
|
||||||
UINT32 pdrEnd = pdrBegin + calculateRegionSize(regionSection->PdrBase, regionSection->PdrLimit);
|
QByteArray padding;
|
||||||
|
|
||||||
UINT32 offset = descriptor.size();
|
|
||||||
// Reconstruct other regions
|
|
||||||
char empty = '\xFF';
|
|
||||||
for (int i = 1; i < model->rowCount(index); i++) {
|
for (int i = 1; i < model->rowCount(index); i++) {
|
||||||
QByteArray region;
|
QModelIndex currentRegion = index.child(i, 0);
|
||||||
result = buildRegion(index.child(i, 0), region);
|
// Skip regions with Remove action
|
||||||
if (result)
|
if (model->action(currentRegion) == Actions::Remove)
|
||||||
return result;
|
continue;
|
||||||
|
|
||||||
UINT8 type = model->subtype(index.child(i, 0));
|
// Check item type to be either region or padding
|
||||||
switch (type)
|
UINT8 type = model->type(currentRegion);
|
||||||
{
|
if (type == Types::Padding) {
|
||||||
|
if (!padding.isEmpty()) {
|
||||||
|
msg(tr("buildIntelImage: more than one padding found during image rebuild, the latest one is used"), index);
|
||||||
|
}
|
||||||
|
padding = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check region subtype
|
||||||
|
STATUS result;
|
||||||
|
UINT8 regionType = model->subtype(currentRegion);
|
||||||
|
switch (regionType) {
|
||||||
case Subtypes::GbeRegion:
|
case Subtypes::GbeRegion:
|
||||||
gbe = region;
|
if (!gbe.isEmpty()) {
|
||||||
if (gbeBegin > offset)
|
msg(tr("buildIntelImage: more than one GbE region found during image rebuild, the latest one is used"), index);
|
||||||
intelImage.append(QByteArray(gbeBegin - offset, empty));
|
}
|
||||||
intelImage.append(gbe);
|
result = buildGbeRegion(currentRegion, gbe);
|
||||||
offset = gbeEnd;
|
if (result) {
|
||||||
|
msg(tr("buildIntelImage: building of GbE region failed with error \"%1\", original item data used").arg(errorCodeToQString(result)), currentRegion);
|
||||||
|
gbe = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Subtypes::MeRegion:
|
case Subtypes::MeRegion:
|
||||||
me = region;
|
if (!me.isEmpty()) {
|
||||||
if (meBegin > offset)
|
msg(tr("buildIntelImage: more than one ME region found during image rebuild, the latest one is used"), index);
|
||||||
intelImage.append(QByteArray(meBegin - offset, empty));
|
}
|
||||||
intelImage.append(me);
|
result = buildMeRegion(currentRegion, me);
|
||||||
offset = meEnd;
|
if (result) {
|
||||||
|
msg(tr("buildIntelImage: building of ME region failed with error \"%1\", original item data used").arg(errorCodeToQString(result)), currentRegion);
|
||||||
|
me = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Subtypes::BiosRegion:
|
case Subtypes::BiosRegion:
|
||||||
bios = region;
|
if (!bios.isEmpty()) {
|
||||||
if (biosBegin > offset)
|
msg(tr("buildIntelImage: more than one BIOS region found during image rebuild, the latest one is used"), index);
|
||||||
intelImage.append(QByteArray(biosBegin - offset, empty));
|
}
|
||||||
intelImage.append(bios);
|
result = buildRawArea(currentRegion, bios);
|
||||||
offset = biosEnd;
|
if (result) {
|
||||||
|
msg(tr("buildIntelImage: building of BIOS region failed with error \"%1\", original item data used").arg(errorCodeToQString(result)), currentRegion);
|
||||||
|
bios = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Subtypes::PdrRegion:
|
case Subtypes::PdrRegion:
|
||||||
pdr = region;
|
if (!pdr.isEmpty()) {
|
||||||
if (pdrBegin > offset)
|
msg(tr("buildIntelImage: more than one PDR region found during image rebuild, the latest one is used"), index);
|
||||||
intelImage.append(QByteArray(pdrBegin - offset, empty));
|
}
|
||||||
intelImage.append(pdr);
|
result = buildPdrRegion(currentRegion, pdr);
|
||||||
offset = pdrEnd;
|
if (result) {
|
||||||
|
msg(tr("buildIntelImage: building of PDR region failed with error \"%1\", original item data used").arg(errorCodeToQString(result)), currentRegion);
|
||||||
|
pdr = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Subtypes::EcRegion:
|
||||||
|
if (!ec.isEmpty()) {
|
||||||
|
msg(tr("buildIntelImage: more than one EC region found during image rebuild, the latest one is used"), index);
|
||||||
|
}
|
||||||
|
result = buildEcRegion(currentRegion, ec);
|
||||||
|
if (result) {
|
||||||
|
msg(tr("buildIntelImage: building of EC region failed with error \"%1\", original item data used").arg(errorCodeToQString(result)), currentRegion);
|
||||||
|
ec = model->header(currentRegion).append(model->body(currentRegion));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg(tr("buildIntelImage: unknown region type found"), index);
|
msg(tr("buildIntelImage: don't know how to build region of unknown type"), index);
|
||||||
return ERR_INVALID_REGION;
|
return ERR_UNKNOWN_ITEM_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if ((UINT32)model->body(index).size() > offset)
|
|
||||||
intelImage.append(QByteArray((UINT32)model->body(index).size() - offset, empty));
|
|
||||||
|
|
||||||
// Check size of new image, it must be same as old one
|
// Check size of new image, it must be same as old one
|
||||||
UINT32 newSize = intelImage.size();
|
UINT32 newSize = intelImage.size();
|
||||||
@ -228,80 +254,23 @@ STATUS FfsBuilder::buildIntelImage(const QModelIndex & index, QByteArray & intel
|
|||||||
return ERR_NOT_IMPLEMENTED;
|
return ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS FfsBuilder::buildRegion(const QModelIndex & index, QByteArray & region)
|
STATUS FfsBuilder::buildGbeRegion(const QModelIndex & index, QByteArray & region)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
return ERR_NOT_IMPLEMENTED;
|
||||||
return ERR_SUCCESS;
|
}
|
||||||
|
|
||||||
UINT8 result;
|
STATUS FfsBuilder::buildMeRegion(const QModelIndex & index, QByteArray & region)
|
||||||
|
{
|
||||||
|
return ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
// No action required
|
STATUS FfsBuilder::buildPdrRegion(const QModelIndex & index, QByteArray & region)
|
||||||
if (model->action(index) == Actions::NoAction) {
|
{
|
||||||
region = model->header(index).append(model->body(index));
|
return ERR_NOT_IMPLEMENTED;
|
||||||
return ERR_SUCCESS;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Erase
|
STATUS FfsBuilder::buildEcRegion(const QModelIndex & index, QByteArray & region)
|
||||||
else if (model->action(index) == Actions::Erase) {
|
{
|
||||||
region = model->header(index).append(model->body(index));
|
|
||||||
if (erase(index, region))
|
|
||||||
msg(tr("buildRegion: erase failed, original item data used"), index);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuild or replace
|
|
||||||
else if (model->action(index) == Actions::Rebuild ||
|
|
||||||
model->action(index) == Actions::Replace) {
|
|
||||||
if (model->rowCount(index)) {
|
|
||||||
region.clear();
|
|
||||||
// Build 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("buildRegion: 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("buildRegion: 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
|
|
||||||
region.append(currentData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
region = model->body(index);
|
|
||||||
|
|
||||||
// Check size of new region, it must be same as original one
|
|
||||||
UINT32 newSize = region.size();
|
|
||||||
UINT32 oldSize = model->body(index).size();
|
|
||||||
if (newSize > oldSize) {
|
|
||||||
msg(tr("buildRegion: new region size %1h (%2) is bigger than the original %3h (%4)")
|
|
||||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
else if (newSize < oldSize) {
|
|
||||||
msg(tr("buildRegion: new region size %1h (%2) is smaller than the original %3h (%4)")
|
|
||||||
.hexarg(newSize).arg(newSize).hexarg(oldSize).arg(oldSize), index);
|
|
||||||
return ERR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build successful
|
|
||||||
region = model->header(index).append(region);
|
|
||||||
return ERR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(tr("buildRegion: unexpected action \"%1\"").arg(actionTypeToQString(model->action(index))), index);
|
|
||||||
return ERR_NOT_IMPLEMENTED;
|
return ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,10 @@ private:
|
|||||||
// UEFI standard structures
|
// UEFI standard structures
|
||||||
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
|
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
|
||||||
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
|
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
|
||||||
STATUS buildRegion(const QModelIndex & index, QByteArray & region);
|
STATUS buildGbeRegion(const QModelIndex & index, QByteArray & region);
|
||||||
|
STATUS buildMeRegion(const QModelIndex & index, QByteArray & region);
|
||||||
|
STATUS buildPdrRegion(const QModelIndex & index, QByteArray & region);
|
||||||
|
STATUS buildEcRegion(const QModelIndex & index, QByteArray & region);
|
||||||
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true);
|
STATUS buildRawArea(const QModelIndex & index, QByteArray & rawArea, bool addHeader = true);
|
||||||
STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
|
STATUS buildPadding(const QModelIndex & index, QByteArray & padding);
|
||||||
STATUS buildVolume(const QModelIndex & index, QByteArray & volume);
|
STATUS buildVolume(const QModelIndex & index, QByteArray & volume);
|
||||||
|
@ -94,22 +94,18 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||||
QByteArray body = buffer.mid(capsuleHeaderSize);
|
QByteArray body = buffer.mid(capsuleHeaderSize);
|
||||||
QString name = tr("UEFI capsule");
|
QString name = tr("UEFI capsule");
|
||||||
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
QString info = tr("Capsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
||||||
.arg(guidToQString(capsuleHeader->CapsuleGuid))
|
.arg(guidToQString(capsuleHeader->CapsuleGuid))
|
||||||
.hexarg(buffer.size()).arg(buffer.size())
|
.hexarg(buffer.size()).arg(buffer.size())
|
||||||
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
||||||
.hexarg(capsuleHeader->CapsuleImageSize - capsuleHeaderSize).arg(capsuleHeader->CapsuleImageSize - capsuleHeaderSize)
|
.hexarg(capsuleHeader->CapsuleImageSize - capsuleHeaderSize).arg(capsuleHeader->CapsuleImageSize - capsuleHeaderSize)
|
||||||
.hexarg2(capsuleHeader->Flags, 8);
|
.hexarg2(capsuleHeader->Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
|
||||||
pdata.fixed = TRUE;
|
|
||||||
|
|
||||||
// Set capsule offset fixup for correct volume allignment warnings
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
capsuleOffsetFixup = capsuleHeaderSize;
|
capsuleOffsetFixup = capsuleHeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, name, QString(), info, header, body, TRUE, QByteArray(), root);
|
||||||
}
|
}
|
||||||
// Check buffer for being Toshiba capsule header
|
// Check buffer for being Toshiba capsule header
|
||||||
else if (buffer.startsWith(TOSHIBA_CAPSULE_GUID)) {
|
else if (buffer.startsWith(TOSHIBA_CAPSULE_GUID)) {
|
||||||
@ -132,22 +128,18 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||||
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
||||||
QString name = tr("Toshiba capsule");
|
QString name = tr("Toshiba capsule");
|
||||||
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
QString info = tr("Capsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
||||||
.arg(guidToQString(capsuleHeader->CapsuleGuid))
|
.arg(guidToQString(capsuleHeader->CapsuleGuid))
|
||||||
.hexarg(buffer.size()).arg(buffer.size())
|
.hexarg(buffer.size()).arg(buffer.size())
|
||||||
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
||||||
.hexarg(capsuleHeader->FullSize - capsuleHeaderSize).arg(capsuleHeader->FullSize - capsuleHeaderSize)
|
.hexarg(capsuleHeader->FullSize - capsuleHeaderSize).arg(capsuleHeader->FullSize - capsuleHeaderSize)
|
||||||
.hexarg2(capsuleHeader->Flags, 8);
|
.hexarg2(capsuleHeader->Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
|
||||||
pdata.fixed = TRUE;
|
|
||||||
|
|
||||||
// Set capsule offset fixup for correct volume allignment warnings
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
capsuleOffsetFixup = capsuleHeaderSize;
|
capsuleOffsetFixup = capsuleHeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, Subtypes::ToshibaCapsule, name, QString(), info, header, body, TRUE, QByteArray(), 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)) {
|
||||||
@ -175,22 +167,18 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||||
QByteArray body = buffer.mid(capsuleHeaderSize);
|
QByteArray body = buffer.mid(capsuleHeaderSize);
|
||||||
QString name = tr("AMI Aptio capsule");
|
QString name = tr("AMI Aptio capsule");
|
||||||
QString info = tr("Offset: 0h\nCapsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
QString info = tr("Capsule GUID: %1\nFull size: %2h (%3)\nHeader size: %4h (%5)\nImage size: %6h (%7)\nFlags: %8h")
|
||||||
.arg(guidToQString(capsuleHeader->CapsuleHeader.CapsuleGuid))
|
.arg(guidToQString(capsuleHeader->CapsuleHeader.CapsuleGuid))
|
||||||
.hexarg(buffer.size()).arg(buffer.size())
|
.hexarg(buffer.size()).arg(buffer.size())
|
||||||
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
.hexarg(capsuleHeaderSize).arg(capsuleHeaderSize)
|
||||||
.hexarg(capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize).arg(capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize)
|
.hexarg(capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize).arg(capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize)
|
||||||
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
.hexarg2(capsuleHeader->CapsuleHeader.Flags, 8);
|
||||||
|
|
||||||
// Construct parsing data
|
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(QModelIndex());
|
|
||||||
pdata.fixed = TRUE;
|
|
||||||
|
|
||||||
// Set capsule offset fixup for correct volume allignment warnings
|
// Set capsule offset fixup for correct volume allignment warnings
|
||||||
capsuleOffsetFixup = capsuleHeaderSize;
|
capsuleOffsetFixup = capsuleHeaderSize;
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, parsingDataToQByteArray(pdata), root);
|
index = model->addItem(Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, QString(), info, header, body, TRUE, QByteArray(), root);
|
||||||
|
|
||||||
// Show message about possible Aptio signature break
|
// Show message about possible Aptio signature break
|
||||||
if (signedCapsule) {
|
if (signedCapsule) {
|
||||||
@ -220,16 +208,14 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex &
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("UEFI image");
|
QString name = tr("UEFI image");
|
||||||
QString info = tr("Offset: %1h\nFull size: %2h (%3)")
|
QString info = tr("Full size: %2h (%3)").hexarg(flashImage.size()).arg(flashImage.size());
|
||||||
.hexarg(capsuleHeaderSize).hexarg(flashImage.size()).arg(flashImage.size());
|
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Parse the image
|
// Parse the image
|
||||||
result = parseRawArea(flashImage, biosIndex);
|
result = parseRawArea(flashImage, biosIndex);
|
||||||
@ -460,19 +446,16 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
|
|||||||
.arg(descriptorMap->NumberOfProcStraps);
|
.arg(descriptorMap->NumberOfProcStraps);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = parentOffset;
|
pdata.offset = parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Image, Subtypes::IntelImage, name, QString(), info, QByteArray(), intelImage, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Descriptor
|
// Descriptor
|
||||||
// Get descriptor info
|
// Get descriptor info
|
||||||
QByteArray body = intelImage.left(FLASH_DESCRIPTOR_SIZE);
|
QByteArray body = intelImage.left(FLASH_DESCRIPTOR_SIZE);
|
||||||
name = tr("Descriptor region");
|
name = tr("Descriptor region");
|
||||||
info = tr("Full size: %1h (%2)").hexarg(FLASH_DESCRIPTOR_SIZE).arg(FLASH_DESCRIPTOR_SIZE);
|
info = tr("Full size: %1h (%2)").hexarg(FLASH_DESCRIPTOR_SIZE).arg(FLASH_DESCRIPTOR_SIZE);
|
||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
|
||||||
|
|
||||||
// Check regions presence once again
|
// Check regions presence once again
|
||||||
QVector<UINT32> offsets;
|
QVector<UINT32> offsets;
|
||||||
@ -569,7 +552,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add descriptor tree item
|
// Add descriptor tree item
|
||||||
model->addItem(Types::Region, Subtypes::DescriptorRegion, name, QString(), info, QByteArray(), body, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::Region, Subtypes::DescriptorRegion, name, QString(), info, QByteArray(), body, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
|
|
||||||
// Sort regions in ascending order
|
// Sort regions in ascending order
|
||||||
qSort(offsets);
|
qSort(offsets);
|
||||||
@ -638,12 +621,10 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 pa
|
|||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = IntelDataEnd;
|
pdata.offset = IntelDataEnd;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the last VTF is found
|
// Check if the last VTF is found
|
||||||
@ -684,12 +665,10 @@ STATUS FfsParser::parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffs
|
|||||||
.arg(version->minor);
|
.arg(version->minor);
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::GbeRegion, name, QString(), info, QByteArray(), gbe, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -745,12 +724,10 @@ STATUS FfsParser::parseMeRegion(const QByteArray & me, const UINT32 parentOffset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::MeRegion, name, QString(), info, QByteArray(), me, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (emptyRegion) {
|
if (emptyRegion) {
|
||||||
@ -778,12 +755,10 @@ STATUS FfsParser::parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffs
|
|||||||
hexarg(pdr.size()).arg(pdr.size());
|
hexarg(pdr.size()).arg(pdr.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::PdrRegion, name, QString(), info, QByteArray(), pdr, TRUE, 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);
|
||||||
@ -808,12 +783,10 @@ STATUS FfsParser::parseEcRegion(const QByteArray & ec, const UINT32 parentOffset
|
|||||||
hexarg(ec.size()).arg(ec.size());
|
hexarg(ec.size()).arg(ec.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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(), ec, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::EcRegion, name, QString(), info, QByteArray(), ec, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -833,12 +806,10 @@ STATUS FfsParser::parseBiosRegion(const QByteArray & bios, const UINT32 parentOf
|
|||||||
hexarg(bios.size()).arg(bios.size());
|
hexarg(bios.size()).arg(bios.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Region, Subtypes::BiosRegion, name, QString(), info, QByteArray(), bios, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return parseRawArea(bios, index);
|
return parseRawArea(bios, index);
|
||||||
}
|
}
|
||||||
@ -882,12 +853,10 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = offset + headerSize;
|
pdata.offset = offset + headerSize;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for and parse all volumes
|
// Search for and parse all volumes
|
||||||
@ -908,12 +877,10 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = offset + headerSize + paddingOffset;
|
pdata.offset = offset + headerSize + paddingOffset;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get volume size
|
// Get volume size
|
||||||
@ -942,12 +909,10 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = offset + headerSize + volumeOffset;
|
pdata.offset = offset + headerSize + volumeOffset;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, 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
|
||||||
@ -987,12 +952,10 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde
|
|||||||
.hexarg(padding.size()).arg(padding.size());
|
.hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset = offset + headerSize + volumeOffset;
|
pdata.offset = offset + headerSize + volumeOffset;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse bodies
|
// Parse bodies
|
||||||
@ -1112,7 +1075,7 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
// Acquire alignment
|
// Acquire alignment
|
||||||
alignment = (UINT32)pow(2.0, (int)(volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
|
alignment = (UINT32)pow(2.0, (int)(volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);
|
||||||
// Check alignment
|
// Check alignment
|
||||||
if (!isUnknown && pdata.isOnFlash && ((pdata.offset + parentOffset - capsuleOffsetFixup) % alignment))
|
if (!isUnknown && !model->compressed(parent) && ((pdata.offset + parentOffset - capsuleOffsetFixup) % alignment))
|
||||||
msgUnaligned = true;
|
msgUnaligned = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1178,7 +1141,6 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = TRUE;
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
pdata.emptyByte = emptyByte;
|
pdata.emptyByte = emptyByte;
|
||||||
pdata.ffsVersion = ffsVersion;
|
pdata.ffsVersion = ffsVersion;
|
||||||
@ -1189,7 +1151,6 @@ STATUS FfsParser::parseVolumeHeader(const QByteArray & volume, const UINT32 pare
|
|||||||
pdata.volume.hasAppleCrc32 = hasAppleCrc32;
|
pdata.volume.hasAppleCrc32 = hasAppleCrc32;
|
||||||
pdata.volume.hasAppleFSO = hasAppleFSO;
|
pdata.volume.hasAppleFSO = hasAppleFSO;
|
||||||
pdata.volume.isWeakAligned = (volumeHeader->Revision > 1 && (volumeHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT));
|
pdata.volume.isWeakAligned = (volumeHeader->Revision > 1 && (volumeHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT));
|
||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
|
||||||
|
|
||||||
// Add text
|
// Add text
|
||||||
QString text;
|
QString text;
|
||||||
@ -1206,7 +1167,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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Volume, subtype, name, text, info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (isUnknown)
|
if (isUnknown)
|
||||||
@ -1298,7 +1259,6 @@ STATUS FfsParser::parseVolumeNonUefiData(const QByteArray & data, const UINT32 p
|
|||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||||
|
|
||||||
// Modify it
|
// Modify it
|
||||||
pdata.fixed = TRUE; // Non-UEFI data is fixed
|
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
|
|
||||||
// Search for VTF GUID backwards in received data
|
// Search for VTF GUID backwards in received data
|
||||||
@ -1322,10 +1282,9 @@ STATUS FfsParser::parseVolumeNonUefiData(const QByteArray & data, const UINT32 p
|
|||||||
// Add non-UEFI data first
|
// Add non-UEFI data first
|
||||||
// Get info
|
// Get info
|
||||||
QString info = tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size());
|
QString info = tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size());
|
||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
|
||||||
|
|
||||||
// Add padding tree item
|
// Add padding tree item
|
||||||
QModelIndex paddingIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, parsingDataToQByteArray(pdata), index);
|
QModelIndex paddingIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
msg(tr("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex);
|
msg(tr("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex);
|
||||||
|
|
||||||
if (vtfIndex >= 0) {
|
if (vtfIndex >= 0) {
|
||||||
@ -1346,10 +1305,9 @@ STATUS FfsParser::parseVolumeNonUefiData(const QByteArray & data, const UINT32 p
|
|||||||
pdata.offset += vtfIndex;
|
pdata.offset += vtfIndex;
|
||||||
// Get info
|
// Get info
|
||||||
QString info = tr("Full size: %1h (%2)").hexarg(vtf.size()).arg(vtf.size());
|
QString info = tr("Full size: %1h (%2)").hexarg(vtf.size()).arg(vtf.size());
|
||||||
if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset));
|
|
||||||
|
|
||||||
// Add padding tree item
|
// Add padding tree item
|
||||||
QModelIndex paddingIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), vtf, parsingDataToQByteArray(pdata), index);
|
QModelIndex paddingIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), vtf, TRUE, parsingDataToQByteArray(pdata), index);
|
||||||
msg(tr("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex);
|
msg(tr("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1403,7 +1361,6 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
i = ALIGN8(i) - 8;
|
i = ALIGN8(i) - 8;
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = FALSE; // Free space is not fixed
|
|
||||||
pdata.offset = offset + volumeHeaderSize + fileOffset;
|
pdata.offset = offset + volumeHeaderSize + fileOffset;
|
||||||
|
|
||||||
// Add all bytes before as free space
|
// Add all bytes before as free space
|
||||||
@ -1412,10 +1369,9 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString info = tr("Full size: %1h (%2)").hexarg(free.size()).arg(free.size());
|
QString info = tr("Full size: %1h (%2)").hexarg(free.size()).arg(free.size());
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), free, FALSE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse non-UEFI data
|
// Parse non-UEFI data
|
||||||
@ -1423,15 +1379,13 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = FALSE; // Free space is not fixed
|
|
||||||
pdata.offset = offset + volumeHeaderSize + fileOffset;
|
pdata.offset = offset + volumeHeaderSize + fileOffset;
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString info = tr("Full size: %1h (%2)").hexarg(freeSpace.size()).arg(freeSpace.size());
|
QString info = tr("Full size: %1h (%2)").hexarg(freeSpace.size()).arg(freeSpace.size());
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Volume free space"), "", info, QByteArray(), freeSpace, FALSE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
break; // Exit from parsing loop
|
break; // Exit from parsing loop
|
||||||
}
|
}
|
||||||
@ -1647,14 +1601,13 @@ STATUS FfsParser::parseFileHeader(const QByteArray & file, const UINT32 parentOf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.fixed = fileHeader->Attributes & FFS_ATTRIB_FIXED;
|
bool fixed = fileHeader->Attributes & FFS_ATTRIB_FIXED;
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
pdata.file.hasTail = hasTail ? TRUE : FALSE;
|
pdata.file.hasTail = hasTail ? TRUE : FALSE;
|
||||||
pdata.file.tail = tail;
|
pdata.file.tail = tail;
|
||||||
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, text, info, header, body, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::File, fileHeader->Type, name, text, info, header, body, fixed, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Overwrite lastVtf, if needed
|
// Overwrite lastVtf, if needed
|
||||||
if (isVtf) {
|
if (isVtf) {
|
||||||
@ -1758,10 +1711,9 @@ STATUS FfsParser::parsePadFileBody(const QModelIndex & index)
|
|||||||
|
|
||||||
// Constuct parsing data
|
// Constuct parsing data
|
||||||
pdata.offset += model->header(index).size();
|
pdata.offset += model->header(index).size();
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
model->addItem(Types::FreeSpace, 0, tr("Free space"), QString(), info, QByteArray(), free, FALSE, parsingDataToQByteArray(pdata), index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1774,11 +1726,9 @@ STATUS FfsParser::parsePadFileBody(const QModelIndex & index)
|
|||||||
|
|
||||||
// Constuct parsing data
|
// Constuct parsing data
|
||||||
pdata.offset += i;
|
pdata.offset += i;
|
||||||
pdata.fixed = TRUE; // This data is fixed
|
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, TRUE, 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);
|
||||||
@ -1815,12 +1765,10 @@ STATUS FfsParser::parseSections(const QByteArray & sections, const QModelIndex &
|
|||||||
QString info = tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size());
|
QString info = tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size());
|
||||||
|
|
||||||
// Constuct parsing data
|
// Constuct parsing data
|
||||||
pdata.fixed = TRUE; // Non-UEFI data is fixed
|
|
||||||
pdata.offset += headerSize + sectionOffset;
|
pdata.offset += headerSize + sectionOffset;
|
||||||
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, parsingDataToQByteArray(pdata), index);
|
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, tr("Non-UEFI data"), "", info, QByteArray(), padding, TRUE, 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);
|
||||||
@ -1849,9 +1797,6 @@ STATUS FfsParser::parseSections(const QByteArray & sections, const QModelIndex &
|
|||||||
case Types::Padding:
|
case Types::Padding:
|
||||||
// No parsing required
|
// No parsing required
|
||||||
break;
|
break;
|
||||||
case Types::Signature:
|
|
||||||
// No parsing required
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return ERR_UNKNOWN_ITEM_TYPE;
|
return ERR_UNKNOWN_ITEM_TYPE;
|
||||||
}
|
}
|
||||||
@ -1923,10 +1868,9 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1972,10 +1916,9 @@ STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const
|
|||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
pdata.section.compressed.compressionType = compressionType;
|
pdata.section.compressed.compressionType = compressionType;
|
||||||
pdata.section.compressed.uncompressedSize = uncompressedLength;
|
pdata.section.compressed.uncompressedSize = uncompressedLength;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2104,10 +2047,9 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
pdata.section.guidDefined.guid = guid;
|
pdata.section.guidDefined.guid = guid;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (msgNoAuthStatusAttribute)
|
if (msgNoAuthStatusAttribute)
|
||||||
@ -2163,10 +2105,9 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
|
|||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
pdata.section.freeformSubtypeGuid.guid = guid;
|
pdata.section.freeformSubtypeGuid.guid = guid;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Rename section
|
// Rename section
|
||||||
model->setName(index, guidToQString(guid));
|
model->setName(index, guidToQString(guid));
|
||||||
@ -2210,10 +2151,9 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
|
|||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2254,10 +2194,9 @@ STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const U
|
|||||||
|
|
||||||
// Construct parsing data
|
// Construct parsing data
|
||||||
pdata.offset += parentOffset;
|
pdata.offset += parentOffset;
|
||||||
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, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2330,9 +2269,10 @@ STATUS FfsParser::parseCompressedSectionBody(const QModelIndex & index)
|
|||||||
// Add info
|
// Add info
|
||||||
model->addInfo(index, tr("\nCompression algorithm: %1").arg(compressionTypeToQString(algorithm)));
|
model->addInfo(index, tr("\nCompression algorithm: %1").arg(compressionTypeToQString(algorithm)));
|
||||||
|
|
||||||
// Update parsing data
|
// Update data
|
||||||
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
|
||||||
pdata.section.compressed.algorithm = algorithm;
|
pdata.section.compressed.algorithm = algorithm;
|
||||||
|
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
||||||
|
model->setCompressed(index, true);
|
||||||
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
||||||
|
|
||||||
// Parse decompressed data
|
// Parse decompressed data
|
||||||
@ -2396,8 +2336,9 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
|
|||||||
// Add info
|
// Add info
|
||||||
model->addInfo(index, info);
|
model->addInfo(index, info);
|
||||||
|
|
||||||
// Update parsing data
|
// Update data
|
||||||
pdata.isOnFlash = (algorithm == COMPRESSION_ALGORITHM_NONE); // Data is not on flash unless not compressed
|
if (algorithm != COMPRESSION_ALGORITHM_NONE)
|
||||||
|
model->setCompressed(index, true);
|
||||||
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
model->setParsingData(index, parsingDataToQByteArray(pdata));
|
||||||
|
|
||||||
if (!parseCurrentSection) {
|
if (!parseCurrentSection) {
|
||||||
@ -2758,13 +2699,15 @@ STATUS FfsParser::performSecondPass(const QModelIndex & index)
|
|||||||
if (!index.isValid() || !lastVtf.isValid())
|
if (!index.isValid() || !lastVtf.isValid())
|
||||||
return ERR_INVALID_PARAMETER;
|
return ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
// Get parsing data for the last VTF
|
// Check for compressed lastVtf
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(lastVtf);
|
if (model->compressed(lastVtf)) {
|
||||||
if (!pdata.isOnFlash) {
|
|
||||||
msg(tr("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf);
|
msg(tr("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get parsing data for the last VTF
|
||||||
|
PARSING_DATA pdata = parsingDataFromQModelIndex(lastVtf);
|
||||||
|
|
||||||
// Calculate address difference
|
// Calculate address difference
|
||||||
const UINT32 vtfSize = model->header(lastVtf).size() + model->body(lastVtf).size() + (pdata.file.hasTail ? sizeof(UINT16) : 0);
|
const UINT32 vtfSize = model->header(lastVtf).size() + model->body(lastVtf).size() + (pdata.file.hasTail ? sizeof(UINT16) : 0);
|
||||||
const UINT32 diff = 0xFFFFFFFFUL - pdata.offset - vtfSize + 1;
|
const UINT32 diff = 0xFFFFFFFFUL - pdata.offset - vtfSize + 1;
|
||||||
@ -2781,11 +2724,14 @@ STATUS FfsParser::addMemoryAddressesRecursive(const QModelIndex & index, const U
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
|
||||||
|
// Set address value for non-compressed data
|
||||||
|
if (!model->compressed(index)) {
|
||||||
// Get parsing data for the current item
|
// Get parsing data for the current item
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||||
|
|
||||||
// Set address value for non-compressed data
|
// Show offset
|
||||||
if (pdata.isOnFlash) {
|
model->addInfo(index, tr("Offset: %1h\n").hexarg(pdata.offset), false);
|
||||||
|
|
||||||
// Check address sanity
|
// Check address sanity
|
||||||
if ((const UINT64)diff + pdata.offset <= 0xFFFFFFFFUL) {
|
if ((const UINT64)diff + pdata.offset <= 0xFFFFFFFFUL) {
|
||||||
// Update info
|
// Update info
|
||||||
@ -2800,7 +2746,7 @@ STATUS FfsParser::addMemoryAddressesRecursive(const QModelIndex & index, const U
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special case of uncompressed TE image sections
|
// Special case of uncompressed TE image sections
|
||||||
if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_TE && pdata.isOnFlash) {
|
if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_TE) {
|
||||||
// Check data memory address to be equal to either ImageBase or AdjustedImageBase
|
// Check data memory address to be equal to either ImageBase or AdjustedImageBase
|
||||||
if (pdata.section.teImage.imageBase == pdata.address + headerSize) {
|
if (pdata.section.teImage.imageBase == pdata.address + headerSize) {
|
||||||
pdata.section.teImage.revision = 1;
|
pdata.section.teImage.revision = 1;
|
||||||
@ -2819,6 +2765,10 @@ STATUS FfsParser::addMemoryAddressesRecursive(const QModelIndex & index, const U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: debugging, don't shows FIT file fixed attribute correctly
|
||||||
|
model->addInfo(index, tr("\nCompressed: %1").arg(model->compressed(index) ? tr("Yes") : tr("No")));
|
||||||
|
model->addInfo(index, tr("\nFixed: %1").arg(model->fixed(index) ? tr("Yes") : tr("No")));
|
||||||
|
|
||||||
// Process child items
|
// Process child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
addMemoryAddressesRecursive(index.child(i, 0), diff);
|
addMemoryAddressesRecursive(index.child(i, 0), diff);
|
||||||
|
@ -58,14 +58,8 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
|
|||||||
if (!fitIndex.isValid())
|
if (!fitIndex.isValid())
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
|
||||||
// Get parsing data for the current item
|
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(fitIndex);
|
|
||||||
|
|
||||||
// Explicitly set the item as fixed
|
// Explicitly set the item as fixed
|
||||||
pdata.fixed = TRUE;
|
model->setFixed(index, true);
|
||||||
|
|
||||||
// Set modified parsing data
|
|
||||||
model->setParsingData(fitIndex, parsingDataToQByteArray(pdata));
|
|
||||||
|
|
||||||
// Special case of FIT header
|
// Special case of FIT header
|
||||||
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset);
|
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset);
|
||||||
@ -98,7 +92,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
|
|||||||
fitTable.append(currentStrings);
|
fitTable.append(currentStrings);
|
||||||
|
|
||||||
// Process all other entries
|
// Process all other entries
|
||||||
bool modifiedImageMayNotWork = false;
|
bool msgModifiedImageMayNotWork = false;
|
||||||
for (UINT32 i = 1; i < fitHeader->Size; i++) {
|
for (UINT32 i = 1; i < fitHeader->Size; i++) {
|
||||||
currentStrings.clear();
|
currentStrings.clear();
|
||||||
const FIT_ENTRY* currentEntry = fitHeader + i;
|
const FIT_ENTRY* currentEntry = fitHeader + i;
|
||||||
@ -121,7 +115,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
|
|||||||
case FIT_TYPE_AC_KEY_MANIFEST:
|
case FIT_TYPE_AC_KEY_MANIFEST:
|
||||||
case FIT_TYPE_AC_BOOT_POLICY:
|
case FIT_TYPE_AC_BOOT_POLICY:
|
||||||
default:
|
default:
|
||||||
modifiedImageMayNotWork = true;
|
msgModifiedImageMayNotWork = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +128,7 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn
|
|||||||
fitTable.append(currentStrings);
|
fitTable.append(currentStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiedImageMayNotWork)
|
if (msgModifiedImageMayNotWork)
|
||||||
msg(tr("Opened image may not work after any modification"));
|
msg(tr("Opened image may not work after any modification"));
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
@ -79,8 +79,6 @@ typedef struct _SECTION_PARSING_DATA {
|
|||||||
} SECTION_PARSING_DATA;
|
} SECTION_PARSING_DATA;
|
||||||
|
|
||||||
typedef struct _PARSING_DATA {
|
typedef struct _PARSING_DATA {
|
||||||
BOOLEAN fixed;
|
|
||||||
BOOLEAN isOnFlash;
|
|
||||||
UINT8 emptyByte;
|
UINT8 emptyByte;
|
||||||
UINT8 ffsVersion;
|
UINT8 ffsVersion;
|
||||||
UINT32 offset;
|
UINT32 offset;
|
||||||
|
@ -17,7 +17,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype,
|
TreeItem::TreeItem(const UINT8 type, const UINT8 subtype,
|
||||||
const QString & name, const QString & text, const QString & info,
|
const QString & name, const QString & text, const QString & info,
|
||||||
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
|
const QByteArray & header, const QByteArray & body,
|
||||||
|
const BOOLEAN fixed, const BOOLEAN compressed, const QByteArray & parsingData,
|
||||||
TreeItem *parent) :
|
TreeItem *parent) :
|
||||||
itemAction(Actions::NoAction),
|
itemAction(Actions::NoAction),
|
||||||
itemType(type),
|
itemType(type),
|
||||||
@ -28,23 +29,11 @@ TreeItem::TreeItem(const UINT8 type, const UINT8 subtype,
|
|||||||
itemHeader(header),
|
itemHeader(header),
|
||||||
itemBody(body),
|
itemBody(body),
|
||||||
itemParsingData(parsingData),
|
itemParsingData(parsingData),
|
||||||
|
itemFixed(fixed),
|
||||||
|
itemCompressed(compressed),
|
||||||
parentItem(parent)
|
parentItem(parent)
|
||||||
{
|
{
|
||||||
}
|
setFixed(fixed);
|
||||||
|
|
||||||
TreeItem::~TreeItem()
|
|
||||||
{
|
|
||||||
qDeleteAll(childItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::appendChild(TreeItem *item)
|
|
||||||
{
|
|
||||||
childItems.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::prependChild(TreeItem *item)
|
|
||||||
{
|
|
||||||
childItems.prepend(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 TreeItem::insertChildBefore(TreeItem *item, TreeItem *newItem)
|
UINT8 TreeItem::insertChildBefore(TreeItem *item, TreeItem *newItem)
|
||||||
@ -65,21 +54,6 @@ UINT8 TreeItem::insertChildAfter(TreeItem *item, TreeItem *newItem)
|
|||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *TreeItem::child(int row)
|
|
||||||
{
|
|
||||||
return childItems.value(row, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeItem::childCount() const
|
|
||||||
{
|
|
||||||
return childItems.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeItem::columnCount() const
|
|
||||||
{
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant TreeItem::data(int column) const
|
QVariant TreeItem::data(int column) const
|
||||||
{
|
{
|
||||||
switch (column)
|
switch (column)
|
||||||
@ -99,46 +73,6 @@ QVariant TreeItem::data(int column) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *TreeItem::parent()
|
|
||||||
{
|
|
||||||
return parentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TreeItem::name() const
|
|
||||||
{
|
|
||||||
return itemName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setName(const QString &name)
|
|
||||||
{
|
|
||||||
itemName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TreeItem::text() const
|
|
||||||
{
|
|
||||||
return itemText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setText(const QString &text)
|
|
||||||
{
|
|
||||||
itemText = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TreeItem::info() const
|
|
||||||
{
|
|
||||||
return itemInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::addInfo(const QString &info)
|
|
||||||
{
|
|
||||||
itemInfo += info;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setInfo(const QString &info)
|
|
||||||
{
|
|
||||||
itemInfo = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TreeItem::row() const
|
int TreeItem::row() const
|
||||||
{
|
{
|
||||||
if (parentItem)
|
if (parentItem)
|
||||||
@ -146,79 +80,3 @@ int TreeItem::row() const
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 TreeItem::type() const
|
|
||||||
{
|
|
||||||
return itemType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setType(const UINT8 type)
|
|
||||||
{
|
|
||||||
itemType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT8 TreeItem::subtype() const
|
|
||||||
{
|
|
||||||
return itemSubtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setSubtype(const UINT8 subtype)
|
|
||||||
{
|
|
||||||
itemSubtype = subtype;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray TreeItem::header() const
|
|
||||||
{
|
|
||||||
return itemHeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray TreeItem::body() const
|
|
||||||
{
|
|
||||||
return itemBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray TreeItem::parsingData() const
|
|
||||||
{
|
|
||||||
return itemParsingData;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeItem::hasEmptyHeader() const
|
|
||||||
{
|
|
||||||
return itemHeader.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeItem::hasEmptyBody() const
|
|
||||||
{
|
|
||||||
return itemBody.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TreeItem::hasEmptyParsingData() const
|
|
||||||
{
|
|
||||||
return itemParsingData.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setParsingData(const QByteArray & data)
|
|
||||||
{
|
|
||||||
itemParsingData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT8 TreeItem::action() const
|
|
||||||
{
|
|
||||||
return itemAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TreeItem::setAction(const UINT8 action)
|
|
||||||
{
|
|
||||||
itemAction = action;
|
|
||||||
|
|
||||||
// On insert action, set insert action for children
|
|
||||||
if (action == Actions::Insert)
|
|
||||||
for (int i = 0; i < childCount(); i++)
|
|
||||||
child(i)->setAction(Actions::Insert);
|
|
||||||
|
|
||||||
// Set rebuild action for parent, if it has no action now
|
|
||||||
if (parentItem && parentItem->type() != Types::Root
|
|
||||||
&& parentItem->action() == Actions::NoAction)
|
|
||||||
parentItem->setAction(Actions::Rebuild);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -25,53 +25,60 @@ class TreeItem
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TreeItem(const UINT8 type, const UINT8 subtype = 0, const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
|
TreeItem(const UINT8 type, const UINT8 subtype = 0, const QString &name = QString(), const QString &text = QString(), const QString &info = QString(),
|
||||||
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
|
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
|
||||||
|
const BOOLEAN fixed = FALSE, const BOOLEAN compressed = FALSE, const QByteArray & parsingData = QByteArray(),
|
||||||
TreeItem *parent = 0);
|
TreeItem *parent = 0);
|
||||||
~TreeItem();
|
~TreeItem() { qDeleteAll(childItems); }
|
||||||
|
|
||||||
// Operations with items
|
// Operations with items
|
||||||
void appendChild(TreeItem *item);
|
void appendChild(TreeItem *item) { childItems.append(item); }
|
||||||
void prependChild(TreeItem *item);
|
void prependChild(TreeItem *item) { childItems.prepend(item); };
|
||||||
UINT8 insertChildBefore(TreeItem *item, TreeItem *newItem);
|
UINT8 insertChildBefore(TreeItem *item, TreeItem *newItem); // Non-trivial implementation in CPP file
|
||||||
UINT8 insertChildAfter(TreeItem *item, TreeItem *newItem);
|
UINT8 insertChildAfter(TreeItem *item, TreeItem *newItem); // Non-trivial implementation in CPP file
|
||||||
|
|
||||||
// Model support operations
|
// Model support operations
|
||||||
TreeItem *child(int row);
|
TreeItem *child(int row) { return childItems.value(row, NULL); }
|
||||||
int childCount() const;
|
int childCount() const {return childItems.count(); }
|
||||||
int columnCount() const;
|
int columnCount() const { return 5; }
|
||||||
QVariant data(int column) const;
|
QVariant data(int column) const; // Non-trivial implementation in CPP file
|
||||||
int row() const;
|
int row() const; // Non-trivial implementation in CPP file
|
||||||
TreeItem *parent();
|
TreeItem *parent() { return parentItem; }
|
||||||
|
|
||||||
// Reading operations for item parameters
|
// Reading operations for item parameters
|
||||||
QString name() const;
|
QString name() const { return itemName; }
|
||||||
void setName(const QString &text);
|
void setName(const QString &text) { itemName = text; }
|
||||||
|
|
||||||
UINT8 type() const;
|
UINT8 type() const { return itemType; }
|
||||||
void setType(const UINT8 type);
|
void setType(const UINT8 type) { itemType = type; }
|
||||||
|
|
||||||
UINT8 subtype() const;
|
UINT8 subtype() const { return itemSubtype; }
|
||||||
void setSubtype(const UINT8 subtype);
|
void setSubtype(const UINT8 subtype) { itemSubtype = subtype; }
|
||||||
|
|
||||||
QString text() const;
|
QString text() const { return itemText; }
|
||||||
void setText(const QString &text);
|
void setText(const QString &text) { itemText = text; }
|
||||||
|
|
||||||
QByteArray header() const;
|
QByteArray header() const { return itemHeader; }
|
||||||
bool hasEmptyHeader() const;
|
bool hasEmptyHeader() const { return itemHeader.isEmpty(); }
|
||||||
|
|
||||||
QByteArray body() const;
|
QByteArray body() const { return itemBody; };
|
||||||
bool hasEmptyBody() const;
|
bool hasEmptyBody() const { return itemBody.isEmpty(); }
|
||||||
|
|
||||||
QByteArray parsingData() const;
|
QByteArray parsingData() const { return itemParsingData; }
|
||||||
bool hasEmptyParsingData() const;
|
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
|
||||||
void setParsingData(const QByteArray & data);
|
void setParsingData(const QByteArray & data) { itemParsingData = data; }
|
||||||
|
|
||||||
QString info() const;
|
QString info() const { return itemInfo; }
|
||||||
void addInfo(const QString &info);
|
void addInfo(const QString &info, const BOOLEAN append) { if (append) itemInfo.append(info); else itemInfo.prepend(info); }
|
||||||
void setInfo(const QString &info);
|
void setInfo(const QString &info) { itemInfo = info; }
|
||||||
|
|
||||||
UINT8 action() const;
|
UINT8 action() const {return itemAction; }
|
||||||
void setAction(const UINT8 action);
|
void setAction(const UINT8 action) { itemAction = action; }
|
||||||
|
|
||||||
|
BOOLEAN fixed() const { return itemFixed; }
|
||||||
|
void setFixed(const bool fixed) { itemFixed = fixed; }
|
||||||
|
|
||||||
|
BOOLEAN compressed() const { return itemCompressed; }
|
||||||
|
void setCompressed(const bool compressed) { itemCompressed = compressed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<TreeItem*> childItems;
|
QList<TreeItem*> childItems;
|
||||||
@ -84,7 +91,9 @@ private:
|
|||||||
QByteArray itemHeader;
|
QByteArray itemHeader;
|
||||||
QByteArray itemBody;
|
QByteArray itemBody;
|
||||||
QByteArray itemParsingData;
|
QByteArray itemParsingData;
|
||||||
TreeItem *parentItem;
|
bool itemFixed;
|
||||||
|
bool itemCompressed;
|
||||||
|
TreeItem* parentItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,6 +226,58 @@ UINT8 TreeModel::action(const QModelIndex &index) const
|
|||||||
return item->action();
|
return item->action();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TreeModel::fixed(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return false;
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
return item->fixed();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TreeModel::compressed(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return false;
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
return item->compressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeModel::setFixed(const QModelIndex &index, const bool fixed)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
item->setFixed(fixed);
|
||||||
|
|
||||||
|
if (!item->parent())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fixed) {
|
||||||
|
if (item->compressed() && item->parent()->compressed() == FALSE) {
|
||||||
|
item->setFixed(item->parent()->fixed());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->parent()->type() != Types::Root)
|
||||||
|
item->parent()->setFixed(fixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeModel::setCompressed(const QModelIndex &index, const bool compressed)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
|
item->setCompressed(compressed);
|
||||||
|
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TreeModel::setSubtype(const QModelIndex & index, const UINT8 subtype)
|
void TreeModel::setSubtype(const QModelIndex & index, const UINT8 subtype)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
@ -276,13 +328,13 @@ void TreeModel::setInfo(const QModelIndex &index, const QString &data)
|
|||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeModel::addInfo(const QModelIndex &index, const QString &data)
|
void TreeModel::addInfo(const QModelIndex &index, const QString &data, const bool append)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
item->addInfo(data);
|
item->addInfo(data, (BOOLEAN)append);
|
||||||
emit dataChanged(index, index);
|
emit dataChanged(index, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,7 +345,18 @@ void TreeModel::setAction(const QModelIndex &index, const UINT8 action)
|
|||||||
|
|
||||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||||
item->setAction(action);
|
item->setAction(action);
|
||||||
emit dataChanged(this->index(0, 0), index);
|
|
||||||
|
// On insert action, set insert action for children
|
||||||
|
if (action == Actions::Insert)
|
||||||
|
for (int i = 0; i < item->childCount(); i++)
|
||||||
|
setAction(index.child(i, 0), Actions::Insert);
|
||||||
|
|
||||||
|
// Set rebuild action for parent, if it has no action now
|
||||||
|
if (index.parent().isValid() && this->type(index.parent()) != Types::Root
|
||||||
|
&& this->action(index.parent()) == Actions::NoAction)
|
||||||
|
setAction(index.parent(), Actions::Rebuild);
|
||||||
|
|
||||||
|
emit dataChanged(index, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
|
void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
|
||||||
@ -308,7 +371,8 @@ void TreeModel::setParsingData(const QModelIndex &index, const QByteArray &data)
|
|||||||
|
|
||||||
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
|
QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
|
||||||
const QString & name, const QString & text, const QString & info,
|
const QString & name, const QString & text, const QString & info,
|
||||||
const QByteArray & header, const QByteArray & body, const QByteArray & parsingData,
|
const QByteArray & header, const QByteArray & body,
|
||||||
|
const bool fixed, const QByteArray & parsingData,
|
||||||
const QModelIndex & parent, const UINT8 mode)
|
const QModelIndex & parent, const UINT8 mode)
|
||||||
{
|
{
|
||||||
TreeItem *item = 0;
|
TreeItem *item = 0;
|
||||||
@ -330,7 +394,8 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, parsingData, parentItem);
|
TreeItem *newItem = new TreeItem(type, subtype, name, text, info, header, body, fixed, this->compressed(parent), parsingData, parentItem);
|
||||||
|
|
||||||
if (mode == CREATE_MODE_APPEND) {
|
if (mode == CREATE_MODE_APPEND) {
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
parentItem->appendChild(newItem);
|
parentItem->appendChild(newItem);
|
||||||
@ -354,7 +419,9 @@ QModelIndex TreeModel::addItem(const UINT8 type, const UINT8 subtype,
|
|||||||
|
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
|
|
||||||
return createIndex(newItem->row(), parentColumn, newItem);
|
QModelIndex created = createIndex(newItem->row(), parentColumn, newItem);
|
||||||
|
setFixed(created, fixed); // Non-trivial logic requires additional call
|
||||||
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex TreeModel::findParentOfType(const QModelIndex& index, UINT8 type) const
|
QModelIndex TreeModel::findParentOfType(const QModelIndex& index, UINT8 type) const
|
||||||
|
@ -48,8 +48,10 @@ public:
|
|||||||
void setName(const QModelIndex &index, const QString &name);
|
void setName(const QModelIndex &index, const QString &name);
|
||||||
void setText(const QModelIndex &index, const QString &text);
|
void setText(const QModelIndex &index, const QString &text);
|
||||||
void setInfo(const QModelIndex &index, const QString &info);
|
void setInfo(const QModelIndex &index, const QString &info);
|
||||||
void addInfo(const QModelIndex &index, const QString &info);
|
void addInfo(const QModelIndex &index, const QString &info, const bool append = TRUE);
|
||||||
void setParsingData(const QModelIndex &index, const QByteArray &data);
|
void setParsingData(const QModelIndex &index, const QByteArray &data);
|
||||||
|
void setFixed(const QModelIndex &index, const bool fixed);
|
||||||
|
void setCompressed(const QModelIndex &index, const bool compressed);
|
||||||
|
|
||||||
QString name(const QModelIndex &index) const;
|
QString name(const QModelIndex &index) const;
|
||||||
QString text(const QModelIndex &index) const;
|
QString text(const QModelIndex &index) const;
|
||||||
@ -63,10 +65,14 @@ public:
|
|||||||
QByteArray parsingData(const QModelIndex &index) const;
|
QByteArray parsingData(const QModelIndex &index) const;
|
||||||
bool hasEmptyParsingData(const QModelIndex &index) const;
|
bool hasEmptyParsingData(const QModelIndex &index) const;
|
||||||
UINT8 action(const QModelIndex &index) const;
|
UINT8 action(const QModelIndex &index) const;
|
||||||
|
bool fixed(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
bool compressed(const QModelIndex &index) const;
|
||||||
|
|
||||||
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0,
|
QModelIndex addItem(const UINT8 type, const UINT8 subtype = 0,
|
||||||
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
|
const QString & name = QString(), const QString & text = QString(), const QString & info = QString(),
|
||||||
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(), const QByteArray & parsingData = QByteArray(),
|
const QByteArray & header = QByteArray(), const QByteArray & body = QByteArray(),
|
||||||
|
const bool fixed = false, const QByteArray & parsingData = QByteArray(),
|
||||||
const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
|
const QModelIndex & parent = QModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
|
|
||||||
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;
|
QModelIndex findParentOfType(const QModelIndex & index, UINT8 type) const;
|
||||||
|
@ -29,6 +29,8 @@ QString regionTypeToQString(const UINT8 type)
|
|||||||
return QObject::tr("BIOS");
|
return QObject::tr("BIOS");
|
||||||
case Subtypes::PdrRegion:
|
case Subtypes::PdrRegion:
|
||||||
return QObject::tr("PDR");
|
return QObject::tr("PDR");
|
||||||
|
case Subtypes::EcRegion:
|
||||||
|
return QObject::tr("EC");
|
||||||
default:
|
default:
|
||||||
return QObject::tr("Unknown");
|
return QObject::tr("Unknown");
|
||||||
};
|
};
|
||||||
@ -55,8 +57,6 @@ QString itemTypeToQString(const UINT8 type)
|
|||||||
return QObject::tr("Section");
|
return QObject::tr("Section");
|
||||||
case Types::FreeSpace:
|
case Types::FreeSpace:
|
||||||
return QObject::tr("Free space");
|
return QObject::tr("Free space");
|
||||||
case Types::Signature:
|
|
||||||
return QObject::tr("Signature");
|
|
||||||
default:
|
default:
|
||||||
return QObject::tr("Unknown");
|
return QObject::tr("Unknown");
|
||||||
}
|
}
|
||||||
@ -110,13 +110,6 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
|||||||
return sectionTypeToQString(subtype);
|
return sectionTypeToQString(subtype);
|
||||||
case Types::FreeSpace:
|
case Types::FreeSpace:
|
||||||
return QString();
|
return QString();
|
||||||
case Types::Signature:
|
|
||||||
if (subtype == Subtypes::UefiSignature)
|
|
||||||
return QObject::tr("UEFI");
|
|
||||||
else if (subtype == Subtypes::Pkcs7Signature)
|
|
||||||
return QObject::tr("PKCS#7");
|
|
||||||
else
|
|
||||||
return QObject::tr("Unknown subtype");
|
|
||||||
default:
|
default:
|
||||||
return QObject::tr("Unknown subtype");
|
return QObject::tr("Unknown subtype");
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ namespace Types {
|
|||||||
Volume,
|
Volume,
|
||||||
File,
|
File,
|
||||||
Section,
|
Section,
|
||||||
Signature,
|
|
||||||
FreeSpace
|
FreeSpace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -71,7 +70,8 @@ namespace Subtypes {
|
|||||||
GbeRegion,
|
GbeRegion,
|
||||||
MeRegion,
|
MeRegion,
|
||||||
BiosRegion,
|
BiosRegion,
|
||||||
PdrRegion
|
PdrRegion,
|
||||||
|
EcRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PaddingSubtypes {
|
enum PaddingSubtypes {
|
||||||
@ -79,11 +79,6 @@ namespace Subtypes {
|
|||||||
OnePadding,
|
OnePadding,
|
||||||
DataPadding
|
DataPadding
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SignatureSubtypes {
|
|
||||||
UefiSignature = 120,
|
|
||||||
Pkcs7Signature
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *ToQString conversion routines
|
// *ToQString conversion routines
|
||||||
|
@ -24,12 +24,11 @@ PARSING_DATA parsingDataFromQModelIndex(const QModelIndex & index)
|
|||||||
{
|
{
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
TreeModel* model = (TreeModel*)index.model();
|
TreeModel* model = (TreeModel*)index.model();
|
||||||
|
if (!model->hasEmptyParsingData(index))
|
||||||
return *(PARSING_DATA*)model->parsingData(index).data();
|
return *(PARSING_DATA*)model->parsingData(index).data();
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSING_DATA data;
|
PARSING_DATA data;
|
||||||
data.fixed = FALSE; // Item is not fixed by default
|
|
||||||
data.isOnFlash = TRUE; // Data is on flash by default
|
|
||||||
data.offset = 0;
|
data.offset = 0;
|
||||||
data.address = 0;
|
data.address = 0;
|
||||||
data.ffsVersion = 0; // Unknown by default
|
data.ffsVersion = 0; // Unknown by default
|
||||||
@ -186,8 +185,13 @@ STATUS decompress(const QByteArray & compressedData, UINT8 & algorithm, QByteArr
|
|||||||
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
|
try {
|
||||||
decompressed = new UINT8[decompressedSize];
|
decompressed = new UINT8[decompressedSize];
|
||||||
scratch = new UINT8[scratchSize];
|
scratch = new UINT8[scratchSize];
|
||||||
|
}
|
||||||
|
catch (std::bad_alloc) {
|
||||||
|
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
// Decompress section data
|
// Decompress section data
|
||||||
|
|
||||||
@ -222,7 +226,12 @@ STATUS decompress(const QByteArray & compressedData, UINT8 & algorithm, QByteArr
|
|||||||
return ERR_CUSTOMIZED_DECOMPRESSION_FAILED;
|
return ERR_CUSTOMIZED_DECOMPRESSION_FAILED;
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
|
try {
|
||||||
decompressed = new UINT8[decompressedSize];
|
decompressed = new UINT8[decompressedSize];
|
||||||
|
}
|
||||||
|
catch (std::bad_alloc) {
|
||||||
|
return ERR_STANDARD_DECOMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
// Decompress section data
|
// Decompress section data
|
||||||
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
if (ERR_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user